1

Pardon for being naive. This is a simple simple question but i am unable to figure out how to query this

PhpmyAdmin pic

Query :

I have 2 tables

kknagar_data & kknagar_rates

I am trying to query out in such a way that

  1. get current record from kknagar_data - i was able to achieve this
  2. get kk_egg,kk_cash of previous record from current in kknagar_data
  3. get rates from kknagar_rates by joining kk_rate_id in kk_nagar_rates & kk_nagar_data - I was able to achieve this

What i am trying to achieve

I want all the above 3 points in a single query.

I was able to do point 1 & 3 and i queried like this

SELECT kk_data_id,kk_date,kk_egg,kk_cash,kk_in,kk_out,kk_expenditure,..... from kknagar_data INNER JOIN kknagar_rates on kknagar_data.kk_rate_id = kknagar_rates.kk_rate_id"

but i am unable add point 2 to the above query so that i get all the data in a single shot

What i tried :

I tried with Unions but i get error because the columns doesnt match

What i am using now :

Currently i use 2 different queries to achieve the above

SELECT kk_data_id,kk_date,kk_egg,kk_cash,kk_in,kk_out,kk_expenditure,..... from kknagar_data INNER JOIN kknagar_rates on kknagar_data.kk_rate_id = kknagar_rates.kk_rate_id"

and

Select kk_egg,kk_cash FROM kknagar_data WHERE kk_data_id < 3 ORDER BY kk_data_id DESC LIMIT 1

It gives me the result but i am trying to change this to make it more efficient. Another reason is when i json out the values, i find it difficult to decode multiple objects.

Goal :

Get current record with 2 fields of previous record and join with kk_nagar_rates & kk_nagar_data using rate_id

Any guindance will be much helpful.

Thanks in Advance

joanolo
13.7k8 gold badges39 silver badges67 bronze badges
asked Mar 25, 2017 at 5:18

1 Answer 1

3

You can use two nearly identical subqueries in your original SELECT:

SELECT 
 kk_data_id,
 kk_date,
 kk_egg,
 kk_cash,
 kk_in,
 kk_out,
 kk_expenditure,
 ( SELECT kk_egg -- You get kk_egg from the "previous" row
 FROM kknagar_data k2 
 WHERE k2.kk_data_id < k1.kk_data_id 
 ORDER BY kk_data_id DESC
 LIMIT 1
 ) AS prev_kk_egg,
 ( SELECT kk_cash -- You get kk_cash from the "previous" row
 FROM kknagar_data k2 
 WHERE k2.kk_data_id < k1.kk_data_id 
 ORDER BY kk_data_id DESC 
 LIMIT 1
 ) AS prev_kk_cash
FROM 
 kknagar_data k1
 INNER JOIN kknagar_rates kr on kr.kk_rate_id = k1.kk_rate_id ;

Having two subqueries looking for two different columns on the same row looks like a waste of time, but it basically mimics what you're doing right now and it works.

You can check it at SQLFiddle.

Note on aliases

You have one table (kknagar_data) that is accessed for three different purposes. First you use it to get the list of "normal records". That's when this table is used as kknagar_data k1 (which can also be written as kknagar_data AS k1). The k1 is just an alias for the table, within that specific context.

Then, in your subqueries, you also refer to the same table, but for a different purpose. In that case, I've used a different alias (FROM kknagar_data **k2**), so that I can refer to the same table with two different contexts. The condition k2.kk_data_id < k1.kk_data_id means: look at the same table (k2 and k1 are actually the same table), but right now (k2) choose the ids that are less than the ones for the "normal records" (k1).

Both subqueries use k2 as an alias because I just copied and pasted the code, and changed the column name. That's possible because the symbol k2 is local to each subquery, and cannot be used outside of its context. That's the same as using the same variable name in two adjacent blocks of a program written in, let's say, Java. It is not advisable to use the same alias when one block contains the other, because you would have, at least, ambiguities.

Aliases are needed when you refer more than once to the same table. For instance, when you have self-referencing tables (i.e.: a table persons where you have a parent-child relationship), or when you want to access "a record of the same table somehow related to the one you already have", such as in your case. Sometimes it is just used for simplicity (k1 is shorter than kknagar_data).

Window functions as a (better) alternative

Databases allowing for WINDOW functions would let you to use the lag() function to have the same effect, in a more efficient manner. Check Introduction to LEAD and LAG for Microsoft SQL Server. You can achieve the same with PostgreSQL, or also with the latest versions of MariaDB. MySQL 8.0 is going to have window functions as well.

answered Mar 25, 2017 at 22:13
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.