JOIN with condition in SQL Server - sql

I have a view that returns results of a query. The output looks something like this:
ORDER_ID DESC Package_Route_ID
123 ABC 212
456 XYZ 175
I have another table that has full order ID for some of the ORDER_IDs. The table looks like following:
ORDER_ID FULL_ORDER_ID
456 45678
So I want to display FULL_ORDER_ID if ORDER_ID from both the results matches or else it should return ORDER_ID from view.
Desired output:
ORDER_ID DESC Package_Route_ID
123 ABC 212
45678 XYZ 175

You just need left outer join
select isnull(od.FULL_ORDER_ID, v.ORDER_ID) ORDER_ID, v.[DESC], v.Package_Route_ID
from view v
left join ordertable od on od.ORDER_ID = v.ORDER_ID;

Related

Postgres: Convert single rows from multiple tables into multiple rows in a single table

I have data scattered across multiple tables and rows that I'd like to aggregate into a more usable format for my use case. The problem boils down to something like this...
If I have two tables like this:
product_id title_id description_id
1 123 234
2 345 456
3 567 678
product_id additional_info_id
1 789
1 890
2 901
How would I construct a query to return data like this?
product_id content_id content_type
1 123 title
1 234 description
1 789 additional_info
1 890 additional_info
2 345 title
2 456 description
2 901 additional_info
3 567 title
3 678 Description
I found this post and I can construct a query like this
select
p.product_id,
p_content.*
from
product p,
lateral (values
(p.title_id, 'title'),
(p.description_id, 'description')
) p_content (content_id, content_type)
;
to get the data from the product table in the format I need, but I can't figure out how to incorporate the data from the additional_info table.
You can use union all:
select p.product_id, v.content_id, v.content_type
from product p cross join lateral
(values (p.title_id, 'title'),
(p.description_id, 'description')
) v(content_id, content_type)
union all
select product_id, additional_info_id, 'additional_info'
from additional_info ai;

exclude complete record if related table has a certain value

I have CLAIMMASTER table like this
CLAIMNO
123
456
789
and another related table PROCSTATUS like this
CLAIMNO PROCCODE
123 111
123 222
456 111
456 222
789 222
I want to exclude the records from table1 where proccode in table2 is 111
the result should be
CLAIMNO
789
I have tried almost everything i can but the closest result i get is like this
CLAIMNO PROCCODE
123 222
456 222
789 222
I know this should be easy but i can't figure out the query to do this.
please help.
Here is the query
select a.CLAIMNO,b.PROCCODE from dbo.CLAIMMASTER a left join
dbo.PROCSTATUS b on a.CLAIMNO = b.CLAIMNO
where a.CLAIMNO not in (select b.CLAIMNO where b.PROCCODE in ('111'))
If you only need to select claimno then no need to have join.
select a.CLAIMNO from dbo.CLAIMMASTER a
where a.CLAIMNO not in
(select distinct b.CLAIMNO from dbo.PROCSTATUS b where b.PROCCODE = '111')
Also if you have claimno repeated in the claimmaster table then you need to use distinct in the select clause.
select a.CLAIMNO
from dbo.CLAIMMASTER a
inner join dbo.PROCSTATUS b
on a.CLAIMNO = b.CLAIMNO
where a.CLAIMNO not in
(select CLAIMNO FROM dbo.PROCSTATUS where PROCCODE in ('111'))

grouping of order line items for orders

Hi i have a table with orders and order iD as primary key and another table order line itme with line item id and primary key, which alos had order id from order table, i would like to pull the list of orders whrere orders are having more than one line item
example:
Orders
123
456
789
order line items
Line item ID Order ID
abc 123
qwe 456
zxc 789
edc 123
wsx 456
tio 123
zxc 456
Result
Order ID Count of Line Item ID
123 2
456 3
select orderid, count(*)
from orders
group by orderid
You can use group by for aggregation and having for filter the order_id with more than 1
select order_id, count(*)
from order_line_table
group by order_id
having count(*) >1
You can use HAVING:
SELECT order_id, COUNT(order_id) count FROM line_items GROUP BY order_id HAVING count > 1

INSERT new row consolidate similar rows

Here is what I need to accomplish:
INSERT a new row into t_order by combining two or more rows from the same table (t_order) where all values are the same except for order_id (Identity) and order_number
The New Row will represent a consolidated order.
Two orders going to the same address get combined into one
Example Table before Insert
order_id order_number ship_addrs1 ship_to_zip
-------- ------------ ----------- -----------
1 ABC001 111 1st St 11111
2 ABC002 123 Main St 12345 <--- Source Row
3 ABC003 123 Main St 12345 <--- Source Row
4 ABC004 111 2nd St 11111
Result After Insert (Source orders must remain)
order_id order_number ship_addrs1 ship_to_zip
-------- ------------ ----------- -----------
1 ABC001 111 1st St 11111
2 ABC002 123 Main St 12345
3 ABC003 123 Main St 12345
4 ABC004 111 2nd St 11111
5 ABC005 123 Main St 12345 <--- New Row
I have considered using the following code to accomplish this but not sure what I need to do to consolidate the three rows.
SELECT * INTO tmp_order_cosolidation
FROM t_order
WHERE order_id = 1 AND order_number = ABC002
ALTER TABLE tmp_order_cosolidation
DROP COLUMN order_id, ordern_number
INSERT INTO t_order
SELECT *
FROM tmp_order_cosolidation;
DROP TABLE tmp_order_cosolidation ;
Thank you in advance for your answers
Your order table should have a few more columns to show whether the order is a consolidation, eligible for consolidation, or has already been consolidated. Here is my proposed solution, which has added columns. All inferred columns are in CAPS.
--VIEW ROWS TO INSERT
select count(order_id),ship_addrs1,ship_to_zip2
from t_order
where CONSOL_ELIGIBLE = 'Y' and CONSOL_COMPLETED = 'N'
group by ship_addrs1,ship_to_zip2
having count(order_id) > 1
--TEMP TABLE FOR INSERT
declare #tmptable TABLE (total_orders int,ship_addrs1 nvarchar(50),ship_to_zip2 nvarchar(50),CONSOL_ELIGIBLE nvarchar(1))
insert into #tmptable (total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE)
(select count(order_id),ship_addrs1,ship_to_zip2,'N'
from t_order
where CONSOL_ELIGIBLE = 'Y' and CONSOL_COMPLETED = 'N'
group by ship_addrs1,ship_to_zip2
having count(order_id) > 1)
--INSERT FROM TEMP TABLE
insert into ORDER_TABLE (total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE)
(select total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE
from #tmptable)

SQL Server : take 1 to many record set and make 1 record per id

I need some help. I need to take the data from these 3 tables and create an output that looks like below. The plan_name_x and pending_tallyx columns are derived to make one line per claim id. Each claim id can be associated to up to 3 plans and I want to show each plan and tally amounts in one record. What is the best way to do this?
Thanks for any ideas. :)
Output result set needed:
claim_id ac_name plan_name_1 pending_tally1 plan_name_2 Pending_tally2 plan_name_3 pending_tally3
-------- ------- ----------- -------------- ----------- -------------- ----------- --------------
1234 abc cooks delux_prime 22 prime_express 23 standard_prime 2
2341 zzz bakers delpux_prime 22 standard_prime 2 NULL NULL
3412 azb pasta's prime_express 23 NULL NULL NULL NULL
SQL Server 2005 table to use for the above result set:
company_claims
claim_id ac_name
1234 abc cooks
2341 zzz bakers
3412 azb pasta's
claim_plans
claim_id plan_id plan_name
1234 101 delux_prime
1234 102 Prime_express
1234 103 standard_prime
2341 101 delux_prime
2341 103 standard_prime
3412 102 Prime_express
Pending_amounts
claim_id plan_id Pending_tally
1234 101 22
1234 102 23
1234 103 2
2341 101 22
2341 103 2
3412 102 23
If you know that 3 is always the max amount of plans then some left joins will work fine:
select c.claim_id, c.ac_name,
cp1.plan_name as plan_name_1, pa1.pending_tally as pending_tally1,
cp2.plan_name as plan_name_2, pa2.pending_tally as pending_tally2,
cp3.plan_name as plan_name_3, pa3.pending_tally as pending_tally3,
from company_claims c
left join claim_plans cp1 on c.claim_id = cp1.claim_id and cp1.planid = 101
left join claim_plans cp2 on c.claim_id = cp2.claim_id and cp2.planid = 102
left join claim_plans cp3 on c.claim_id = cp3.claim_id and cp3.planid = 103
left join pending_amounts pa1 on cp1.claim_id = pa1.claimid and cp1.planid = pa1.plainid
left join pending_amounts pa2 on cp2.claim_id = pa2.claimid and cp2.planid = pa2.plainid
left join pending_amounts pa3 on cp3.claim_id = pa3.claimid and cp3.planid = pa3.plainid
I would first join all your data so that you get the relevant columns: claim_id, ac_name, plan_name, pending tally.
Then I would add transform this to get plan name and plan tally on different rows, with a label tying them together.
Then it should be easy to pivot.
I would tie these together with common table expressions.
Here's the query:
with X as (
select cc.*, cp.plan_name, pa.pending_tally,
rank() over (partition by cc.claim_id order by plan_name) as r
from company_claims cc
join claim_plans cp on cp.claim_id = cc.claim_id
join pending_amounts pa on pa.claim_id = cp.claim_id
and pa.plan_id = cp.plan_id
), P as (
select
X.claim_id,
x.ac_name,
x.plan_name as value,
'plan_name_' + cast(r as varchar(max)) as label
from x
union all
select
X.claim_id,
x.ac_name,
cast(x.pending_tally as varchar(max)) as value,
'pending_tally' + cast(r as varchar(max)) as label
from x
)
select claim_id, ac_name, [plan_name_1], [pending_tally1],[plan_name_2], [pending_tally2],[plan_name_3], [pending_tally3]
from (select * from P) p
pivot (
max(value)
for label in ([plan_name_1], [pending_tally1],[plan_name_2], [pending_tally2],[plan_name_3], [pending_tally3])
) as pvt
order by pvt.claim_id, ac_name
Here's a fiddle showing it in action: http://sqlfiddle.com/#!3/68f62/10