Need SQL query for the requirement [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 17 days ago.
Improve this question
I have 2 tables table1 and table2 as shown here, and the desired output as below
Table 1:
material_num | product_id
-------------+-------------
ABCDE NULL
THEJR 1ERT34
GTHUJ 23UJ45
HYUIJ E9JLK5
DFOMC NULL
Table 2:
item_number | material_number | id
------------+-----------------+-------
2003 DFOMC 3456
2005 ABCDE 5678
3456 GTHUJ 4857
4003 THEJR 8904
5678 HYUIJ 2002
Expected output:
material_number | product_id
----------------+-------------
ABCDE E9JLK5
THEJR 1ERT34
GTHUJ 23UJ45
HYUIJ E9JLK5
DFOMC 23UJ45
I want to derive the product_id of the material_numbers whose value is null.
The product_id can be derived from the table2 where ID of one material_number = item_number of another material_number, if we found such material number then the product id of such material number will be product if of the material number whose value is null.
Example: the id of material_number ABCDE is 5678, which is the item_number of material_number HYUIJ.
So the product_id of HYUIJ becomes the product_id of ABCDE as well.
I have tried this below query
select
material_number
from
(select material_number
from table2
where item_number in (select id from table2)
) as material_product_id;
Please help to advise on this situation.

try this.
if a value is NULL, I use a subquery to find the corresponding value.
SELECT
a.material_num,
-- if product_id is null, search in table2 with id->item_number for material_number
CASE
WHEN a.product_id IS NULL
THEN (
SELECT b.material_number
FROM TABLE2 c
JOIN TABLE2 b ON c.id = b.item_number
WHERE c.material_number = a.material_num
)
ELSE a.product_id
END AS product_id
FROM TABLE1 a

Related

Delete rows that contain NULLs if row with ID already exists

I have a table as shown below.
If a product id has been entered into the table with a description, I want to delete all other rows with the same product ids where the description is NULL, leaving only the product id with a description. In the table below, I want to delete ROW_ID = 1 and keep ROW_ID = 2.
Furthermore, if a row is present with product id with a NULL description but no other matching product ids, I want to leave that row in the table. In the table below leaving ROW_ID = 3 as it is.
row_id
product_id
product_description
time_stamp
1
000001
null
2012-12-22 20:00:00
2
000001
item description
2012-12-23 21:00:00
3
000002
null
2012-12-23 21:00:00
The resulting table would look like this:
row_id
product_id
product_description
time_stamp
2
000001
item description
2012-12-23 21:00:00
3
000002
null
2012-12-23 21:00:00
Try something like this assuming the table is named products:
DELETE FROM products as p
WHERE p.product_description is null
AND EXISTS (
SELECT * FROM products as p2 WHERE p2.product_id = p.product_id AND p2.product_description IS NOT NULL
);
The EXISTS operator will return true if the subselect returns greater than 0 rows.
You can try like this:
WITH cte
AS ( SELECT * ,ROW_NUMBER() OVER ( PARTITION BY product_id order by time_stamp desc) as rn
FROM t)
DELETE FROM cte
WHERE rn>1 and cte.product_description is null;
select * from t;
FIDDLE DEMO

How do I get the count for orders with a certain code only when there are multiple codes for the same order possible

Sorry this is my first post - please let me know if something doesn't make sense!
I'm trying to get a count of the number of orders with a specific code XXX ONLY
lets say table A looks something like this
|ORDER ID | ITEM CODE |
123 XXX
123 YYY
123 YYY
456 XXX
456 XXX
456 XXX
789 XXX
000 YYY
what i want in the output is:
order 123 and 000 not to count
and order 456 and 789 to count as 1 each
I only want the count of the unique orders which have item code XXX ONLY
so the count/ output of the final query should be 2
currently what i have is
select order_id, item code, count(order_id) from table a
where item code = 'XXX'
group by order_id, item code
order by count(order_id)
which outputs me the following
ORDER_ID | ITEM CODE | COUNT(ORDER_ID)
123 XXX 1
345 XXX 3
789 XXX 1
This is wrong because I want the output as described above
Thanks in advance!
select order_id
from table_a
group by order_id
having min(item_code) = 'XXX'
and max(item_code) = 'XXX'
Seems like you want this :
select distinct order_id , item_code , 1 as count
from table t1
where not exists (
select 1 from table t2
where t1.order_id = t2.order_id
and t2.item_code <> 'XXX'
)
the count would be always 1 per your question
One option is to use an anti-join. For example:
select distinct t.order_id, 1 as cnt
from table_a t
left join table_a u on u.order_id = t.order_id and u.item_code <> 'XXX'
where t.item_code = 'XXX' and u.order_id is null
Result:
ORDER_ID CNT
--------- ---
789 1
456 1
See running example at db<>fiddle.
EDIT
To get the total count only, tweak the query as shown below:
select count(distinct t.order_id) as cnt
from table_a t
left join table_a u on u.order_id = t.order_id and u.item_code <> 'XXX'
where t.item_code = 'XXX' and u.order_id is null
Result:
CNT
---
2
See running example at db<>fiddle.

How to separate comma separate values and get aggregate of a column in SQL?

I have a table T1 as below
product_id val
123,567 5
999 4
999 3
and another table T2,
t_product_id // this maps to product_id in above table
123
999
In the final output, for t_product_id in table T2 I have to get value for it from T1. For duplicate product_ids (999) I want to get the min value, and for 123 I want to get 5
This is how output should look like
product_id value
123 5
999 3
My query ->
select t1.product_id, min(t1.value)
from T1 t1
group by t1.product_id
I am not sure what needs to be done next. How to separate comma separated values and check if 123 from T2 exists in T1 and get the value for it
it's not possible to keep only one product_id per row in table T1?
I think this would simplify matters for you. T1 would be:
123 | 5
567 | 5
999 | 4
999 | 3
Use join to only select the ids that exist in T2
select t1.product_id, min(t1.value)
from T1 t1 join T2 on (t1.product_id = t2.t_product_id)
group by t1.product_id

Returning multiple columns with subquery and 'where in'

I'm having some trouble getting a select query to return the data I need. See the simplified example below.
Sku table
Sku SkuId
==================
ABC-123 123
DEF-456 456
GHI-789 789
JKL-987 987
SkuCombo table
SkuId SkuComboId Qty
===========================
123 456 1
123 789 2
123 987 1
A "combo" item is a sku number given to an item that consists of multiple items. For example, for the sku ABC-123, you would need to look up the Sku from the Sku table to get the SkuId(123), then use the SkuId to get the SkuComboIds (456, 789, 987) from the SkuCombo. Then use those on the Sku table to get he corresponding Sku. The following query almost gets me there, but I don't know how to get the Qty column from the SkuCombo table?:
select *
from Skus
where SkuId in (Select SkuComboId
from SkuCombo sc
join Skus s on s.SkuId = sc.SkuId
where s.Sku = 'ABC-123')
Desired result
Sku SkuId Qty
============================
DEF-456 456 1
GHI-789 789 2
JKL-987 987 1
You need SELF JOIN :
select sk1.Sku , sk1.SkuId, skc.qty
from Sku sk inner join
SkuCombo skc
on skc.SkuId = sk.SkuId inner join
Sku sk1
on sk1.SkuId = skc.SkuComboId;
Not sure if I'm oversimplifying, or don't understand your question 100%, but wouldn't an Inner Join be the answer here:
Select *
from Skus s
join SkuCombo sc on s.SkuId = sc.SkuComboId
This can be done easily done using inner join as there are no null values in either of the table.
SELECT s.Sku, s.SkuId, sc.Qty
FROM SkuCombo sc
INNER JOIN Skus s ON sc.SkuComboId = s.SkuId

Order by data depending on a specific value of column [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i am using Sql server 2008, i need to order by the following data:
Id PId Name
1 1 A
1 2 G --value to consider
1 3 C
2 1 A
2 2 B --value to consider
2 3 C
3 1 A
3 2 D --value to consider
3 3 C
result should look something like:
Id PId Name
2 1 A
2 2 B
2 3 C
3 1 A
3 2 D
3 3 C
1 1 A
1 2 G
1 3 C
i have tried different combinations in order by clause but of no use like:
order by Name, PId
order by PId, Name, Id
select T1.*
from Table1 as t1
left outer join Table1 as T2 on T2.id = T1.id and T2.Pid = 2
order by T2.Name, T1.Pid
sql fiddle demo
Your question isn't clear about the ordering you want, but if you want to order by the Name associated with the same Id for PId=2, then by Pid, try
select Id, PId, Name
from t
order by (
select Name from t as t2
where t2.Id = t.Id
and t2.PId = 2
), PId