I have a certain result-set and I need to group them together on userId.
e.g.
userId 2019-01-15 2019-01-16
------------------------------
132 0 30_140
132 30_140 0
Required output:
userId 2019-01-15 2019-01-16
------------------------------
132 30_140 30_140
Since values contain non-numeric characters, SUM won't work.
If the empty values are all 0 or NULL you can just use MAX:
SELECT userID, MAX(`2019-01-15`) AS `2019-01-15`, MAX(`2019-01-16`) AS `2019-01-16`
FROM test
GROUP BY userID
Output:
userID 2019-01-15 2019-01-16
132 30_140 30_140
Demo on dbfiddle
Related
I need to find in the table scores, the student numbers that has all the grades in between 70 and 90. The answer should only return 105 and 108 since they are the only student numbers that fit the criteria. I keep getting 105,108, and 109 for some reason but I can't see why. This is the table below.
SCORES
sno | grade
101 | 64
109 | 68
105 | 75
109 | 76
108 | 78
107 | 79
108 | 81
101 | 85
NULL | 86
105 | 88
107 | 91
103 | 92
This is the query that is giving me that result.
SELECT sno
FROM scores
GROUP BY sno
HAVING grade BETWEEN 70 and 90;```
I think you're after something like this:
SELECT sno, MIN(grade) as mingrade, MAX(grade) AS maxgrade
FROM scores
GROUP BY sno
HAVING MIN(grade) >= 70 AND MAX(grade) <= 90
but note that this will return the row that has a null value for "sno" because this row fits your criteria. You can always add WHERE sno IS NOT NULL after the FROM scores if you want to exclude that row.
NOTE: Obviously you can leave out the mingrade/maxgrade columns if you don't wish to have them in the result set.
ADDITIONAL NOTE: I presume you are using SQLite? Most other SQL dialects complain about the syntax in your example because they expect an aggregate function to apply on the columns used in the HAVING clause.
For what it's worth, there's an online demo here
What about this:
WITH OUTSIDE_GRADES
AS
(
SELECT SNO FROM SCORES
WHERE 1=1
AND (GRADE < 70 OR GRADE > 90)
)
SELECT distinct SNO FROM SCORES WHERE SNO NOT IN (SELECT SNO FROM
OUTSIDE_GRADES)
I'm currently working on a query that looks like this. There are two tables - members and member_gathering.
SELECT id, city_id, name FROM members
WHERE "id" = "member_id" IN
(
SELECT "member_id" from member_gathering
GROUP BY "member_id"
HAVING COUNT(DATEDIFF("visited","joined">=365))>=5
ORDER BY "member_id"
)
ORDER BY id*1;
The goal is to have an output of all IDs satisfying the condition of being in more than 5 groups, in which a member is active for more than a year. Being active means having a difference between "visited" and "joined" columns (both are TIMESTAMP) for more than a year (I set that as 365 days).
However, after running, this code shows all the rows in a members table (though manual check of both tables shows that some rows do not satisfy both conditions at the same time).
Any ideas on how to improve the code above? I'm not sure if I can use 'nested' condition inside COUNT(), but all other variants used before show either NULL values or returned all rows in the table, which is obviously not right. Also, I was thinking that problem might be with DATEDIFF function.
All suggestions are welcome: I'm a newbie to MySQL, so I'm not that familiar with it.
UPD: data sample:
1) members
id city_id name
2 980 Joey
5 980 Carl
10 1009 Louis
130 1092 Andrea
2) member_gathering
member_id gathering_id joined visited
2 1 2010-01-01 00:00:00 2010-02-01 00:00:00
2 2 2010-01-01 00:00:00 2010-02-01 00:00:00
5 2 2010-01-01 00:00:00 2010-02-01 00:00:00
10 3 2010-01-01 00:00:00 2010-02-01 00:00:00
130 1 2010-02-01 00:00:00 2013-02-01 00:00:00
130 2 2010-02-01 00:00:00 2013-02-01 00:00:00
130 3 2010-02-01 00:00:00 2014-02-01 00:00:00
130 4 2010-02-01 00:00:00 2018-02-01 00:00:00
130 5 2010-02-01 00:00:00 2015-02-01 00:00:00
Expected result would be only ID 130, thus: 130, 1092, Andreana.
I believe you first need to find all records where datediff is 365 days or more. Then find members who have 5 or more such instances. This needs both WHERE and HAVING clause:
SELECT id, city_id, name
FROM members
WHERE id IN (
SELECT member_id
FROM member_gathering
WHERE DATEDIFF(visited, joined) >= 365
GROUP BY member_id
HAVING COUNT(*) >= 5
)
You could use this way
SELECT id, city_id, name FROM members
WHERE member_id IN
(
SELECT member_id from member_gathering
GROUP BY member_id
HAVING SUM(DATEDIFF(visited, joined) >= 365)>=5
ORDER BY member_id
)
You should use separated expression for count differente category of datediff and remmeber that count work for not null values so if you want obtain the totale for true values you should sue SUM
I am looking for a query to return a Column in Sale Table called as MRP. This table has some mistaken values of MRP. where as in Purchase table everything is in order and has right vales of MRP. Needed a query to return the values in the Sale Table which has No matching MRP in Purchase table for individual Item.
Sample Purchase Table
Iid CP QUANTITY MRP PRICE
1 62.8 240 89 78
1 57.5 240 89 79
1 60.15 480 89 79
2 60.14 720 89 79
2 60.15 480 89 79
Sample Sales Table here 2nd row has the Mistaken MRP
iid CP QTY MRP PRICE
1 57.5 240 89 77
1 57.5 40 81 79
1 57.5 40 89 79
1 62.8 40 89 72
1 62.8 40 89 78
Needed a Query to show the id in Sales Table where the ItemID iid and MRP is mistakenly taken when not in the list of Purchases for the same Item
Thank You in Advance.
Using not exists()
select *
from sale s
where not exists (
select 1
from purchase p
where p.iid = s.iid
and p.mrp = s.mrp
)
rextester demo: http://rextester.com/ZICIT13088
returns:
+-----+----+-----+-----+-------+
| iid | cp | qty | mrp | price |
+-----+----+-----+-----+-------+
| 1 | 58 | 40 | 81 | 79 |
+-----+----+-----+-----+-------+
You can use a NOT IN clause to test for values that don't exist. In your case, just source the "NOT IN" values from the purchase table:
SELECT MRP
FROM SalesTable
WHERE Iid NOT IN (SELECT IId FROM PurchaseTable)
This will return the MRP field for all rows in your sales table with "Iid" values that do not have a matching "Iid" value in the PurchaseTable. Depending on your DB version, you may need to add WHERE Iid IS NOT NULL to your sub-select to work with the NOT IN.
You should also be able to use the NOT EXISTS operator to do the same thing.
SELECT id, itemn, CAST(MRP AS NUMERIC(18,0)) as mrp, price
FROM [iBillDB].[dbo].DETAILSALE
WHERE CAST(MRP AS NUMERIC(18,0)) NOT IN (SELECT CAST(MRP AS NUMERIC(18,0)) FROM [iBillDB].[dbo].DETAILPURCHASES) order by id, CAST(itemn AS NUMERIC(18,0)) asc
This Worked For me. Thanks for the Hint #ravioli
I have two tables that aren't really associated, but need to be combined. So I'm using union all on the two tables. The unioned tables are ordered by date, so rows from one table are dispersed among rows from the other table. What I need to do is get a running count of a column so I can group elements.
To explain further, table A holds dates of when a container is emptied, while table B holds daily entries for content of the container. I need to union the two tables so I have one table where I can get the sum of the information for a container before the container is emptied.
So I need something like this:
Table A:
Location_ID Empty Date
123 3/2/13
123 3/10/13
123 4/1/13
Table B:
PSI Entry Date Location_ID
120 2/28/13 123 (same for all)
130 3/1/13
100 3/8/13
110 3/9/13
200 3/18/13
180 3/20/13
So the unioned table after some magic would look like:
Table C...:
Location_ID Date PSI Emptied
123 2/28/13 120 0
123 3/1/13 130 0
123 3/2/13 null 1
123 3/8/13 100 0
123 3/9/13 110 0
123 3/10/13 null 1
123 3/18/13 200 0
123 3/20/13 180 0
123 4/1/13 null 1
What I need to do is have a grouping such that I can have a table like this
Table C_b
Location_ID Date PSI Emptied Group
123 2/28/13 120 0 1
123 3/1/13 130 0 1
123 3/2/13 null 1 1
123 3/8/13 100 0 2
123 3/9/13 110 0 2
123 3/10/13 null 1 2
123 3/18/13 200 0 3
123 3/20/13 180 0 3
123 4/1/13 null 1 3
How can I get that grouping in that way? I have to make it work in SQL Server 2008. I have tried using Count, and Rank, and Row_Number. But the problem with those is that it won't do a running count, it will just say the total count in each row.
Try this query:
DECLARE #MyTable TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL
);
INSERT INTO #MyTable (EntryDate,Emptied)
VALUES
('2013-01-01',0),
('2013-01-02',0),
('2013-01-03',1),
('2013-01-04',0),
('2013-01-05',0),
('2013-01-06',1),
('2013-01-07',0),
('2013-01-08',0),
('2013-01-09',1);
DECLARE #TableWithRowNum TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL,
RowNum INT PRIMARY KEY
);
INSERT INTO #TableWithRowNum (EntryDate,Emptied,RowNum)
SELECT crt.*,ROW_NUMBER() OVER(ORDER BY crt.EntryDate) AS RowNum
FROM #MyTable crt;
WITH RecCTE
AS(
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
1 AS Grp
FROM #TableWithRowNum crt
WHERE crt.RowNum=1
UNION ALL
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
CASE WHEN prev.Emptied=1 THEN prev.Grp+1 ELSE prev.Grp END
FROM #TableWithRowNum crt INNER JOIN RecCTE prev ON crt.RowNum=prev.RowNum+1
)
SELECT * FROM RecCTE
OPTION(MAXRECURSION 0); -- Default value for MAXRECURSION is 100
GO
Results:
EntryDate Emptied RowNum Grp
---------- ------- ------ ---
2013-01-01 0 1 1
2013-01-02 0 2 1
2013-01-03 1 3 1
2013-01-04 0 4 2
2013-01-05 0 5 2
2013-01-06 1 6 2
2013-01-07 0 7 3
2013-01-08 0 8 3
2013-01-09 1 9 3
This is my table structure:
rec_id product_id quantity quantity_in quantity_out balance stock_date status
1 2 342 NULL 17 325 2009-10-23 1
2 2 325 NULL 124 201 2009-10-23 1
3 1 156 NULL 45 111 2009-10-23 1
4 2 201 NULL 200 1 2009-10-23 1
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
All I want is the last transaction done for a given product: product_id, quantity, quantity_out and balance from this table.
Example, there are 2 transaction done for product 2 (ids 1 & 2):
final balance for product_id 2 is 0 -> stored in rec_id 5
final balance for product_id 1 is 76 -> stored in rec_id 6
Final result/output should be like this:
recid productid quantity quantityin quantityout balance stock_date status
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
You can find the latest record for each product like:
select max(rec_id) as MaxRec
from YourTable
group by product_id
Using a subquery, you can retrieve the latest rows for their product:
select *
from YourTable
where rec_id in (
select max(rec_id) as MaxRec
from YourTable
group by product_id
)
Here's a single query with no subqueries:
SELECT main.*
FROM YourTable main
LEFT JOIN YourTable newer
ON newer.product_id = main.product_id AND newer.rec_id > main.rec_id
WHERE newer.rec_id IS NULL;
You can tweak the field list however you want--make sure you select fields from main, not newer, which should be all null.