need help in forming sql query - mysql

i have one master table and 2 tables, one is inward table and the other one is issue_return_broken table.
all the 3 tables are related using the ITEM_CODE (primary key)..
if i run the below 3 queries ,
Master query :
select item_code, item_name , item_spec, item_quantity,item_unitprice,item_value from
ven_inv_partmaster
where item_code ='NAVTES13'
Query 1:
select entry_date, quantity_in from ven_inv_inwardmaster
where item_code ='NAVTES13'
group by entry_date,quantity_in
query 2:
select issue_date, issue_qnty,rtn_qnty,brkn_qnty from ven_inv_ibrmaster_log ibrlog
where ibrlog.item_code ='NAVTES13' and issue_dateid !=0
group by issue_date,issue_qnty,rtn_qnty,brkn_qnty
Query 3:
select rtn_date, rtn_qnty,brkn_qnty from ven_inv_ibrmaster_log ibrlog
where ibrlog.item_code ='NAVTES13' and issue_dateid =0
group by rtn_date,rtn_qnty,brkn_qnty
i am getting the output as below,
item_code item_name item_spec item_quantity item_unitprice item_value
NAVTES13 NAVIN TEST13 175 15.00 2175.00
output1:
entry_date quantity_in
2012-04-01 00:00:00.000 50
2012-04-05 00:00:00.000 50
output 2:
issue_date issue_qnty rtn_qnty brkn_qnty
2012-04-02 00:00:00.000 25 0 0
2012-04-10 00:00:00.000 10 0 0
output 3:
rtn_date rtn_qnty brkn_qnty
2012-04-05 00:00:00.000 10 0
2012-04-10 00:00:00.000 9 6
i need to combine all these queries into a single query and need a result set like this..
Date Quantity_Inward Quantity_Issued Return_Quantity Broken_Quantity
1/4/2012 50 0 0 0
2/4/2012 0 25 0 0
5/4/2012 0 0 10 0
5/4/2012 50 0 0 0
10/4/2012 0 0 9 6
10/4/2012 0 10 0 0
please help me out to solve this query..
inward & ibr master table :

To combine the results of your queries in the manner shown, use UNION with ordering in an outer query:
SELECT
DATE_FORMAT(logdate, '%e/%c/%Y') AS `Date`,
quantity_in AS Quantity_Inward,
issue_qnty AS Quantity_Issued,
rtn_qnty AS Return_Quantity,
brkn_qnty AS Broken_Quantity
FROM (
select date(entry_date) as logdate, quantity_in,
0 as issue_qnty, 0 as rtn_qnty, 0 as brkn_qnty
from ven_inv_inwardmaster
where item_code ='NAVTES13'
UNION ALL
select date(issue_date), 0, issue_qnty, rtn_qnty, brkn_qnty
from ven_inv_ibrmaster_log
where item_code ='NAVTES13' and issue_dateid != 0
UNION ALL
select date(rtn_date), 0, 0, rtn_qnty, brkn_qnty
from ven_inv_ibrmaster_log
where item_code ='NAVTES13' and issue_dateid = 0
) AS t
ORDER BY logdate ASC
You could even aggregate in the outer query if so desired (your sample output doesn't do so):
SELECT
DATE_FORMAT(logdate, '%e/%c/%Y') AS `Date`,
SUM(quantity_in) AS Quantity_Inward,
SUM(issue_qnty) AS Quantity_Issued,
SUM(rtn_qnty) AS Return_Quantity,
SUM(brkn_qnty) AS Broken_Quantity
FROM (
...
) AS t
GROUP BY logdate
ORDER BY logdate ASC
You might improve performance slightly by combining your queries 2 and 3 as follows:
select
date(if(issue_dateid = 0, rtn_date, issue_date)),
if(issue_dateid = 0, 0, issue_qnty),
rtn_qnty,
brkn_qnty
from ven_inv_ibrmaster_log
where item_code = 'NAVTES13'
Note I have removed the GROUP BY clauses from your queries as your comment above suggests they are not required.

Related

Conditional SQL Query on Multiple Rows

I am trying to find out which customers have defaulted on their loans. I would like to query the dataset to find the User_id of customers who have not paid in the last 60 days, but and not sure how to implement this in SQL.
User_id Due_Date Loan_Amount Paid_Amount
1 2012-04-04 16:14:12 500 40
1 2012-05-04 16:14:12 500 40
1 2012-06-04 16:14:12 500 0
1 2012-07-04 16:14:12 500 0
1 2012-08-04 16:14:12 500 0
2 2012-02-15 03:30:55 2030 100
2 2012-03-15 03:30:55 2030 100
2 2012-04-15 03:30:55 2030 100
3 2012-01-03 12:24:42 777 10
3 2012-02-03 12:24:42 777 0
3 2012-03-03 12:24:42 777 0
3 2012-04-03 12:24:42 777 0
In pseudocode (shown in bold) would look something like this, but I can't seem to implement it in MySQL:
SELECT User_id from TABLE_NAME WHERE Loan_Amount > 0 AND [the value Paid_Amount has been null for over 60 days]
Desired Output:
Users 1 and 3 in the above query would be returned because they have not paid for three consecutive periods.
NOTE: Due_Date is a time stamp
Any ideas would be very much appreciated!
Looks like you can use the DATEDIFF(date1, date1) function to obtain a list of delinquent borrowers.
SELECT DISTINCT
user_id
FROM table_name n
JOIN (SELECT user_id, max(due_date) maxDate FROM table_name GROUP BY user_id) t
ON n.user_id = t.user_id
AND n.due_date = t.maxDate
WHERE
loan_amount > 0
AND paid_amount IS NULL
AMD DATEDIFF(due_date, getdate()) > 60
My previous query was wrong, try this
select distinct t1.User_id
from TABLE_NAME t1
inner join (
select ts1.User_id, sum(ts1.Paid_Amount) as Paid_Amount_Total
from TABLE_NAME ts1
group by ts1.User_id
) t2
on t1.User_id=t2.User_id and t1.Loan_Amount>t2.Paid_Amount_Total
)
where
t1.Loan_Amount > 0
and t1.User_id not in (
select ts2.User_id
from TABLE_NAME ts2
where ts2.Due_Date>=DATE_SUB(NOW(), INTERVAL 60 DAY) and ts2.Paid_Amount>0
)
t1, ts1, ts2 - are aliases for TABLE_NAME

Count 2 columns by the same grouping

I'm trying to get two counts of separate columns for data in one table.
I have a database that tracks issues, and one table, Issue, has the 2 relevant columns that each contain a date. Very similar to the following.
DateOpened DateClosed
2015-01-08 2015-01-08
2015-01-08 2015-01-08
2015-01-06 2015-01-08
2015-01-06 2015-01-08
2015-01-04 2015-01-07
2015-01-02 2015-01-07
2015-01-02 2015-01-07
My goal is to be able to count the number of entries opened and closed on each date. An example of the expected output from above would be.
Date CountDateOpened CountDateClosed
2015-01-08 2 4
2015-01-07 0 3
2015-01-06 2 0
2015-01-05 0 0
2015-01-04 1 0
2015-01-03 0 0
2015-01-02 2 0
I know I need to group by Date, but there should be days where more issues are closed than opened, but my COUNT(DateClosed) never seems to exceed my Count(DateOpened). I am doing on the fly date conversions in the query, but I do not believe them to be relevant since I always round to the nearest day. Here is the query I'm running so far, skinned down for simplicity.
SELECT
CREATEDATE AS [Date],
COUNT(CREATEDATE) AS [Number Opened],
COUNT(CLOSEDATE) AS [Number Closed]
FROM
ISSUE
GROUP BY
CREATEDATE
ORDER BY
[Date] DESC
One way of doing this is to use union all to create a single column for both dates and then group according to its type:
SELECT `Date`,
COUNT(`open`) AS `CountDateOpened`
COUNT(`closed`) AS `CountDateClosed`
FROM (SELECT `DateOpened` AS `Date`, 1 AS `open`, NULL AS `closed`
FROM `issue`
UNION ALL
SELECT `DateClosed` AS `Date`, NULL AS `open`, 1 AS `closed`
FROM `issue`
) t
GROUP BY `Date`
ORDER BY `Date` DESC
Try this
select
d.dt,(select COUNT(DateOpened) ct from ISSUE where
CAST(DateOpened as DATE)=CAST(d.dt as DATE) )
,(select COUNT(DateClosed) ct from ISSUE where
CAST(DateClosed as DATE)=CAST(d.dt as DATE) )
from (
select number,DATEADD(D,number-7,GETDATE()) dt
from master.dbo.spt_values sp
where type='P' and DATEADD(D,number-7,GETDATE())<'2015-01-09'
)
d
ORDER BY d.dt desc
OUTPUT
Date DateOpened DateClosed
2015-01-08 2 4
2015-01-07 0 3
2015-01-06 2 0
2015-01-05 0 0
2015-01-04 1 0
2015-01-03 0 0
2015-01-02 2 0
Same as Mureinik's answer, just a little less typing...
SELECT date,SUM(status='opened') opened, SUM(status = 'closed') closed
FROM
( SELECT dateopened date,'opened' status FROM my_table
UNION ALL
SELECT dateclosed,'closed' FROM my_table
) x
GROUP
BY date DESC;

Can anyone help me to write sql statement?

Can anyone help me to write sql below?
Suppose:
tbl_request
No Title Date Priority
1 AAA 2013-08-06 3
2 BBB 2013-08-04 1
3 CCC 2013-08-05 0
4 DDD 2013-08-02 4
5 EEE 2013-08-01 2
6 FFF 2013-08-04 0
7 GGG 2013-08-03 5
8 HHH 2013-08-03 0
There are two top priorities to order in sql statement:
1st priority: Ordering by Priority in Ascending (only 1,2,3,4,5)
2nd priority: Ordering by Date Descending
I want to show all request that order with the 1st priority first (0 won't display). After 1st priority, i want to display the 2nd priority.
Here is what i want:
No Title Date Priority
2 BBB 2013-08-04 1
5 EEE 2013-08-01 2
1 AAA 2013-08-06 3
4 DDD 2013-08-02 4
7 GGG 2013-08-03 5
3 FFF 2013-08-05 0
6 GGG 2013-08-04 0
8 HHH 2013-08-03 0
I don't know how to write sql statement to get the format above. Can anyone tell me how to write it?
Thank in advance.
How about something like
SELECT *
FROM Table1
ORDER BY
CASE WHEN `Priority` != 0 THEN NULL ELSE 1 END,
`Priority`,
`Date` DESC
or
SELECT *
FROM Table1
ORDER BY
CASE WHEN `Priority` != 0 THEN 0 ELSE 1 END,
`Priority`,
`Date` DESC
SQL Fiddle DEMO
This will ensure that even if any of the priorities are greater than the other answers max values, this will still sort 0 as last.
You could try something like:-
SELECT * FROM tbl_request
WHERE Priority IN (1, 2, 3, 4, 5)
ORDER BY Priority, DATE DESC
UNION
SELECT * FROM tbl_request
WHERE Priority NOT IN (1, 2, 3, 4, 5)
ORDER BY Date DESC;
select no,title,date,priority
from tbl_request
order by if(priority=0,99999,priority),date desc
This assumes that no priority is over 99999. Yo also need to pit back quotes around no and date columns - I don't have them on this keyboard!
You should use case expression as below
select No,Title,Date,Priority
from tab
order by
case
when Priority=0 then 9999
else Priority
end,
Date desc
If you aren't displaying 0 Priority records, then the below SQL statement will do just fine.
SELECT * FROM tbl_request WHERE Priority <> 0 ORDER BY Priority ASC, Date DESC
You can try:
Select title, date, priority from tbl_request Order By IF(priority = 0, 99999, priority) asc, date desc
though it is ugly, inefficient, it works for you. Or you can consider making a union of to sub queries
Select title, date, priority from tbl_request where priority > 0 order by priority asc
union
Select title, date, priority from tbl_request where priority = 0 order by date desc
SELECT *
FROM Table1
ORDER BY
(CASE WHEN Priority = 0 THEN 9999 ELSE 1 END) asc, date desc
SELECT *
FROM Table1
ORDER BY field(`Priority`,0),`Priority`,
`Date` DESC
FIDDLE
Select * from tbl_request
Order by ( CASE WHEN Priority > 0 THEN Priority ELSE 99999999 END ), DATE DESC

MySQL select last unique occurrence

Let's say you have the following table (the column of interest here is binid):
id datetime agid binid status
1 2013-02-01 11:03:49 0 25 1
2 2013-02-01 11:03:53 0 25 1
3 2013-02-01 11:04:21 0 26 1
4 2013-02-01 11:04:23 0 26 0
5 2013-03-01 11:04:26 0 25 0
6 2013-03-01 11:04:30 0 36 0
7 2013-03-01 11:04:34 0 36 1
8 2013-03-01 11:04:35 0 36 1
9 2013-03-01 11:04:36 0 36 1
10 2013-03-01 11:04:39 0 36 0
11 2013-03-01 11:04:41 0 36 1
13 2013-03-01 11:04:50 0 25 1
14 2013-03-01 11:04:53 0 26 1
15 2013-03-01 11:15:25 0 25 1
16 2013-03-01 11:15:30 0 25 0
17 2013-03-01 11:15:39 0 23 1
18 2013-03-01 11:15:43 0 26 1
How can I extract the last occurrence of each binid that occurs in a certain timeframe?
This is what I am using so far:
SELECT * FROM ( reports ORDER BY datetime ASC )
WHERE datetime >= TIMESTAMP('2013-03-01')
GROUP BY binid
but it returns the first occurrences instead. How can I return the last occurrence of each unique binid?
You should use a subquery to get the result:
select r1.*
from reports r1
inner join
(
select max(datetime) MaxDate, binid
from reports
WHERE datetime >= TIMESTAMP('2013-03-01')
group by binid
) r2
on r1.binid = r2.binid
and r1.datetime = r2.maxdate
WHERE r1.datetime >= TIMESTAMP('2013-03-01')
See SQL Fiddle with Demo
The problem is that when you are using a GROUP BY on a single column then MySQL can return an unexpected value for the other columns not in the GROUP BY. (see MySQL Extensions to GROUP BY).
From the MySQL Docs:
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. ... You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.
SELECT binid,
SUBSTRING_INDEX(GROUP_CONCAT(agid ORDER BY datetime DESC), ',', 1) AS agid,
SUBSTRING_INDEX(GROUP_CONCAT(status ORDER BY datetime DESC), ',', 1) AS status
FROM reports
WHERE datetime <= TIMESTAMP('2013-03-01')
GROUP BY binid;
SELECT * FROM ( reports ORDER BY datetime DESC)
WHERE datetime >= TIMESTAMP('2013-03-01')
GROUP BY binid LIMIT 1
Change ORDER BY ASC to ORDER BY DESC. Should do the trick.

MySQL query to count non-null values in a single row

I'm trying to put together a MYSQL query that will count the number of Non-Null (or better yet, non-zero) values in select fields in a single row and then sort from lowest to highest (based on the count). For example, I have a table with 5 fields... ID, Name, Score_1, Score_2, Score_3. I want to count how many times the value "0" exists in Score_1, Score_2 and Score_3 for each record, then sort from most non zero values to least.
ID Name Score_1 Score_2 Score_3
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
4 Mike 4 5 5
I assume the query has to look something like this...
Select ID, Name, Score_1, Score_2, Score_3 where (???) ORDER BY (???)
Output should look like this (ID 4 is displayed first since it has the least amount of non-zero entries)...
ID Name Score_1 Score_2 Score_3
4 Mike 4 5 5
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
I'm somewhat new to mysql query's, so any help would be greatly appreciated. I thought the COUNT function would help, but that function appears to count columns from all rows. Perhaps there is a way to use the COUNT function and limit it to a singel row so it can be sorted by that row count?
This should do what you want:
SELECT ID, Name, Score_1, Score_2, Score_3
FROM Table1
ORDER BY (Score_1 = 0) + (Score_2 = 0) + (Score_3 = 0)
Result:
ID Name Score_1 Score_2 Score_3
4 Mike 4 5 5
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
try This:
Select id, Count1, Count2, Count3, Count4
From
(Select
Sum(Case When IsNull(Score_1,0) = 0 Then 1 Else 0 End) Count1,
Sum(Case When IsNull(Score_2,0) = 0 Then 1 Else 0 End) Count2,
Sum(Case When IsNull(Score_3,0) = 0 Then 1 Else 0 End) Count3,
Sum(Case When IsNull(Score_4,0) = 0 Then 1 Else 0 End) Count4
From Table
Group By Id) Z -- This column (Id) better not be the PK for this table!!!
Order By Count1 + Count2 + Count3 + Count4