sqlite return same value on left join - sql

in below my sqlite command i want to get count of barcoeds when that's equals with sessions.id
select sessions.id, sessions.session_name, sessions.session_type,sessions.date_time, count(barcodes.id) as barcode_count
from sessions left join barcodes
on sessions.id = barcodes.session_id
group by barcodes.id
order by sessions.id desc
this command works, but that return more data with same value, for example if data is one, that return more than 3, but really i have one row
0 = {_List} size = 5
0 = 11
1 = "111"
2 = 2
3 = "1398/05/14 ساعت: 08:43"
4 = 1
1 = {_List} size = 5
0 = 11
1 = "111"
2 = 2
3 = "1398/05/14 ساعت: 08:43"
4 = 1
2 = {_List} size = 5
0 = 11
1 = "111"
2 = 2
3 = "1398/05/14 ساعت: 08:43"
4 = 1

I think you want one row per session. So, your query is aggregating by the wrong column:
select s.id, s.session_name, s.session_type,
s.date_time, count(b.id) as barcode_count
from sessions s left join
barcodes b
on s.id = b.session_id
group by s.id
---------^ sessions not barcode
order by s.id desc;
You might find this also easy to do with a correlated subquery:
select s.*,
(select count(*) from barcodes b where b.session_id = s.id)
from sessions s;
The use of table aliases in these queries makes them easier to write and to read.

First count the ids for each session_id in table barcodes and then join to sessions:
select
s.id, s.session_name, s.session_type, s.date_time,
coalesce(b.barcode_count, 0) barcode_count
from sessions s left join (
select session_id, count(id) barcode_count
from barcodes
group by session_id
) b on s.id = b.session_id
order by s.id desc
I guess id is unique in the table barcodes so there is no need for count(distinct id).

Related

sql function case returns more than one row

Going to use this query as a subquery, the problem is it returns many rows of duplicates. Tried to use COUNT() instead of exists, but it still returns a multiple answer.
Every table can only contain one record of superRef.
The below query I`ll use in SELECT col_a, [the CASE] From MyTable
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = myTable.sysno AND A_specAttr = 'value')
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo WHERE C_superRef = myTable.sysno AND b_type = 2)
THEN 2
ELSE (SELECT C_intType FROM C
WHERE C_superRef = myTable.sysno)
END
FROM A, B, C
result:
3
3
3
3
3
3...
What if you did this? Because Im guessing you are getting an implicit full outer join A X B X C then running the case statement for each row in that result set.
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM ( SELECT COUNT(*) FROM A ) --This is a hack but should work in ANSI sql.
--Your milage my vary with different RDBMS flavors.
DUAL is what I needed, thanks to Thorsten Kettner
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM DUAL

Top Row within the Second Table

I'm having an issue with getting TOP to work within my SQL query. I only want to see the first row within the PART_AML table. I'm not having any luck trying to only query that table without querying the PART table.
How can I go about only showing the top row within the PART_AML table? I'm using Microsoft SQL.
Thank you for your help its greatly appreciated.
SELECT innovator.PART.STATE,
innovator.PART.NAME,
innovator.PART.ITEM_NUMBER,
innovator.PART.ID,
innovator.PART.TYPE,
innovator.MANUFACTURER_PART.SPEC_URL
FROM innovator.PART
join innovator.PART_AML
on innovator.PART_AML.SOURCE_ID = innovator.PART.ID
join innovator.MANUFACTURER_PART
on innovator.MANUFACTURER_PART.ID = innovator.PART_AML.RELATED_ID
WHERE
(innovator.PART.IS_CURRENT = 1) AND (innovator.PART_AML.IS_CURRENT = 1) AND (innovator.MANUFACTURER_PART.IS_CURRENT = 1)
Current Output
Number Name ID Type Spec
E000836 1k ID1 Resistor SPEC 1
E000836 1k ID1 Resistor SPEC 2
E000836 1k ID1 Resistor SPEC 3
E003455 14.400MHz ID2 Crystal SPEC 1
E003455 14.400MHz ID2 Crystal SPEC 2
E003455 14.400MHz ID2 Crystal SPEC 3
Preferred Output
Number Name ID Type Spec
E000836 1k ID1 Resistor SPEC 1
E003455 14.400MHz ID2 Crystal SPEC 1
You can make use of the ranking function ROW_NUMBER() OVER(ORDER BY ...) to do this:
WITH CTE
AS
(
SELECT
i.STATE,
i.NAME,
i.ITEM_NUMBER,
i.ID,
i.TYPE,
p.SPEC_URL,
ROW_NUMBER() OVER(PARTITION BY i.ID
ORDER BY p.SPEC_URL) AS Rownum
FROM innovator.PART AS i
INNER JOIN innovator.PART_AML AS a on a.SOURCE_ID = i.ID
INNER JOIN innovator.MANUFACTURER_PART AS p on p.ID = a.RELATED_ID
WHERE i.IS_CURRENT = 1
AND a.IS_CURRENT = 1
AND p.IS_CURRENT = 1
)
SELECT *
FROM CTE
WHERE rownum = 1;
Also you can use simple GROUP BY clause with MIN() function
SELECT innovator.PART.STATE,
innovator.PART.NAME,
innovator.PART.ITEM_NUMBER,
innovator.PART.ID,
innovator.PART.TYPE,
MIN(innovator.MANUFACTURER_PART.SPEC_URL) AS SPEC_URL
FROM innovator.PART join innovator.PART_AML on innovator.PART_AML.SOURCE_ID = innovator.PART.ID
join innovator.MANUFACTURER_PART on innovator.MANUFACTURER_PART.ID = innovator.PART_AML.RELATED_ID
WHERE (innovator.PART.IS_CURRENT = 1) AND (innovator.PART_AML.IS_CURRENT = 1) AND (innovator.MANUFACTURER_PART.IS_CURRENT = 1)
GROUP BY innovator.PART.STATE, innovator.PART.NAME, innovator.PART.ITEM_NUMBER, innovator.PART.ID, innovator.PART.TYPE

Join 2 tables: one data table and one table of statut and get statut with no entrie

I have this query:
SELECT c.Show_Code, req.Statut_ID, COUNT(req.Statut_ID) 'Count'
FROM [Case] c
JOIN Request req ON req.Case_Number = c.Number
GROUP BY c.Show_Code, req.Statut_ID
The result is:
Show_Code Statut_ID Count
564900 2 1
568127 2 1
And I have this statut table (Ref_RequestStatut)
ID Name
1 Test
2 Test2
How can I get this result:
Show_Code Statut_ID Count
564900 1 0
564900 2 1
568127 1 0
568127 2 1
I want all the statut, even those which have no value?
Thank
If you are using SQL Server 2005 or later:
WITH counted AS (
SELECT c.Show_Code, req.Statut_ID, COUNT(req.Statut_ID) 'Count'
FROM [Case] c
JOIN Request req ON req.Case_Number = c.Number
GROUP BY c.Show_Code, req.Statut_ID
),
showcodes AS (
SELECT DISTINCT Show_Code
FROM counted
)
SELECT
s.Show_Code,
r.ID AS Statut_ID,
Count = ISNULL(c.Count, 0)
FROM showcodes s
CROSS JOIN Ref_RequestStatut r
LEFT JOIN counted c ON s.Show_Code = c.Show_Code AND r.ID = c.Statut_ID
ORDER BY
s.Show_Code,
r.ID

SELECT Data from multiple tables?

I have 3 tables, with 3 fields all the same. I basically want to select information from each table
For example:
userid = 1
I want to select data from all 3 tables, where userid = 1
I am currently using:
SELECT r.*,
p.*,
l.*
FROM random r
LEFT JOIN pandom p ON r.userid = p.userid
LEFT JOIN landom l ON l.userid = r.userid
WHERE r.userid = '1'
LIMIT 0, 30
But it doesn't seem to work.
with 3 fields all the same
So you mean that you want the same 3 fields from all 3 tables?
SELECT r.col1, r.col2, r.col3
FROM random r
WHERE r.userid = '1'
LIMIT 0, 30
UNION ALL
SELECT p.pcol1, p.pcol_2, p.p3
FROM pandom p
WHERE p.userid = '1'
LIMIT 0, 30
UNION ALL
SELECT l.l1, l.l2, l.l3
FROM landom l
WHERE l.userid = '1'
LIMIT 0, 30
The fields don't have to be named the same, but the same types need to line up in position 1, 2 and 3.
The way the limits work is:
it will attempt to get 30 from random.
If it has 30 already, it won't even look at the other 2 tables
if it has less than 30 from random, it will try to fill up to 30 from pandom and only finally landom
SELECT t1.*, t2.*, t3.*
FROM `random` as t1, `pandom` as t2, `landom` as t3
WHERE t1.`userid`='1' AND t2.`userid`='1' AND t3.`userid`='1'
SELECT * FROM `random`
JOIN `pandom` USING (`userid`)
JOIN `landom` USING (`userid`)
WHERE `userid`='1'

Using (IN operator) OR condition in Where clause as AND condition

Please look at following image, I have explained my requirements in the image.
alt text http://img30.imageshack.us/img30/5668/shippment.png
I can't use here WHERE UsageTypeid IN(1,2,3,4) because this will behave as an OR condition and fetch all records.
I just want those records, of first table, which are attached with all 4 ShipmentToID .
All others which are attached with 3 or less ShipmentToIDs are not needed in result set.
Thanks.
if (EntityId, UsageTypeId) is unique:
select s.PrimaryKeyField, s.ShipmentId from shipment s, item a
where s.PrimaryKeyField = a.EntityId and a.UsageTypeId in (1,2,3,4)
group by s.PrimaryKeyField, s.ShipmentId having count(*) = 4
otherwise, 4-way join for the 4 fields,
select distinct s.* from shipment s, item a, item b, item c, item d where
s.PrimaryKeyField = a.EntityId = b.EntityId = c.EntityId = d.EntityId and
a.UsageTypeId = 1 and b.UsageTypeId = 2 and c.UsageTypeId = 3 and
d.UsageTypeId = 4
you'll want appropriate index on (EntityId, UsageTypeId) so it doesn't hang...
If there will never be duplicates of the UsageTypeId-EntityId combo in the 2nd table, so you'll never see:
EntityUsageTypeId | EntityId | UsageTypeId
22685 | 4477 | 1
22687 | 4477 | 1
You can count matching EntityIds in that table.
WHERE (count(*) in <tablename> WHERE EntityId = 4477) = 4
DECLARE #numShippingMethods int;
SELECT #numShippingMethods = COUNT(*)
FROM shippedToTable;
SELECT tbl1.shipmentID, COUNT(UsageTypeId) as Usages
FROM tbl2 JOIN tbl1 ON tbl2.EntityId = tbl1.EntityId
GROUP BY tbl1.EntityID
HAVING COUNT(UsageTypeId) = #numShippingMethods
This way is preferred to the multiple join against same table method, as you can simply modify the IN clause and the COUNT without needing to add or subtract more tables to the query when your list of IDs changes:
select EntityId, ShipmentId
from (
select EntityId
from (
select EntityId
from EntityUsage eu
where UsageTypeId in (1,2,3,4)
group by EntityId, UsageTypeId
) b
group by EntityId
having count(*) = 4
) a
inner join Shipment s on a.EntityId = s.EntityId