minus two tables with primary key - sql

I have sql database with tables:
sc: s_id, m_id
s: id, name
m: id, name
sc_standart: s_id, m_id
s_standart: id, name
m_standart: id, name
sc.s_id is from s.id, sc.m_id is from m.id, sc_standart.s_id is from s_standart.id, sc_standart.m_id is from m_standart.id.
I should set m_id=null for all lines from sc which are not exist in sc_standart.
I had already written:
SELECT s.name, m.name
FROM s
JOIN sc
ON s.id=sc.s_id
JOIN m
ON m.id=sc.m_id
MINUS
SELECT s_standart.name, m_standart.name
FROM s_standart
JOIN sc_standart
ON s_standart.id=sc_standart.s_id
JOIN m_standart
ON m_standart.id=sc_standart.m_id
So I should update (s_id, m_id) lines relevant to (s.name, m.name) from the select above.

It looks like you could just do it as:
update sc
set m_id = null
where not exists
( select 1 from sc_standart s
where s.m_id = sc.m_id )
Or using minus:
update sc
set m_id = null
where m_id in
( select m_id from sc
minus
select m_id from sc_standart )
However, I might be missing something as I couldn't see how the other four tables were related to your question.

Related

SQL can not refer table in from clause within where

I have a simple SQL query used in oracle 11g
select something
from sc
where sc.column satisfies something
but I can not refer SC in the where composite, any one can help explain this, thanks in advance.
---second edit: I tested the sql command in oracle 19c it works but in 11g it does not work.
table contents
create table sc(
sno varchar2(10),
cno varchar2(10),
score number(4,2),
constraint pk_sc primary key (sno,cno)
);
example data
insert into sc values ('s001','c001',78.9);
insert into sc values ('s002','c001',80.9);
insert into sc values ('s003','c001',81.9);
insert into sc values ('s004','c001',60.9);
insert into sc values ('s001','c002',82.9);
insert into sc values ('s002','c002',72.9);
insert into sc values ('s003','c002',81.9);
insert into sc values ('s001','c003','59');
sql command
SELECT SNO
FROM SC A
WHERE 0 = (SELECT COUNT(*)
FROM
(SELECT B.CNO
FROM SC B
WHERE B.SNO = 's001'
MINUS
SELECT C.CNO
FROM SC C
WHERE A.SNO = C.SNO) --this is the error location, oracle reports invalid identifier A.
);
I would try a exists clause instead of where 0 =
SELECT SNO
FROM SC A
WHERE not exists (SELECT B.CNO
FROM SC B
WHERE B.SNO = 's001'
MINUS
SELECT C.CNO
FROM SC C
WHERE A.SNO = C.SNO) --this is the error location, oracle reports undefined A.
I'm assuming you want to return where there is not a match?
If you're trying to get the CNO that are not only in SNO 's001'.
Then maybe this.
SELECT DISTINCT SNO, cno
FROM SC sc
WHERE SNO = 's001'
AND EXISTS (
SELECT 1
FROM SC sc2
WHERE sc2.CNO = sc.CNO
AND sc2.SNO != sc.SNO
)

SQL Get all parent and child of active parent

Here is my case I have a table structure like :
I just want to get all active parents (i.e record with name A,E and G) and their child.
The expected result should look like this :
with recursive as (
SELECT par.Id,
par.Name,
par.ParentID,
par.IsDeleted
FROM table1 par
JOIN table1 chi
ON par.Id = chi.ParentId
union all
SELECT par.Id,
par.Name,
par.ParentID,
rec.IsDeleted
FROM table1 par
JOIN recursive rec
ON rec.Id = par.ParentId
),
check_tbl as (
select Id,
sum(IsDeleted) as IsDeleted
from recursive
group by Id
having sum(IsDeleted)=0
)
select table1.id, Name, ParentID, table1.IsDeleted
from check_tbl join table1 on table1.Id=check_tbl.Id
;

Unable to convert this legacy SQL into Standard SQL in Google BigQuery

I am not able to validate this legacy sql into standard bigquery sql as I don't know what else is required to change here(This query fails during validation if I choose standard SQL as big query dialect):
SELECT
lineitem.*,
proposal_lineitem.*,
porder.*,
company.*,
product.*,
proposal.*,
trafficker.name,
salesperson.name,
rate_card.*
FROM (
SELECT
*
FROM
dfp_data.dfp_order_lineitem
WHERE
DATE(end_datetime) >= DATE(DATE_ADD(CURRENT_TIMESTAMP(), -1, 'YEAR'))
OR end_datetime IS NULL ) lineitem
JOIN (
SELECT
*
FROM
dfp_data.dfp_order) porder
ON
lineitem.order_id = porder.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_proposal_lineitem) proposal_lineitem
ON
lineitem.id = proposal_lineitem.dfp_lineitem_id
JOIN (
SELECT
*
FROM
dfp_data.dfp_company) company
ON
porder.advertiser_id = company.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_product) product
ON
proposal_lineitem.product_id=product.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_proposal) proposal
ON
proposal_lineitem.proposal_id=proposal.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_rate_card) rate_card
ON
proposal_lineitem.ratecard_id=rate_card.id
LEFT JOIN (
SELECT
id,
name
FROM
dfp_data.dfp_user) trafficker
ON
porder.trafficker_id =trafficker.id
LEFT JOIN (
SELECT
id,
name
FROM
dfp_data.dfp_user) salesperson
ON
porder. salesperson_id =salesperson.id
Most likely the error you are getting is something like below
Duplicate column names in the result are not supported. Found duplicate(s): name
Legacy SQL adjust trafficker.name and salesperson.name in your SELECT statement into respectively trafficker_name and salesperson_name thus effectively eliminating column names duplication
Standard SQL behaves differently and treat both those columns as named name thus producing duplication case. To avoid it - you just need to provide aliases as in example below
SELECT
lineitem.*,
proposal_lineitem.*,
porder.*,
company.*,
product.*,
proposal.*,
trafficker.name AS trafficker_name,
salesperson.name AS salesperson_name,
rate_card.*
FROM ( ...
You can easily check above explained using below simplified/dummy queries
#legacySQL
SELECT
porder.*,
trafficker.name,
salesperson.name
FROM (
SELECT 1 order_id, 'abc' order_name, 1 trafficker_id, 2 salesperson_id
) porder
LEFT JOIN (SELECT 1 id, 'trafficker' name) trafficker
ON porder.trafficker_id =trafficker.id
LEFT JOIN (SELECT 2 id, 'salesperson' name ) salesperson
ON porder. salesperson_id =salesperson.id
and
#standardSQL
SELECT
porder.*,
trafficker.name AS trafficker_name,
salesperson.name AS salesperson_name
FROM (
SELECT 1 order_id, 'abc' order_name, 1 trafficker_id, 2 salesperson_id
) porder
LEFT JOIN (SELECT 1 id, 'trafficker' name) trafficker
ON porder.trafficker_id =trafficker.id
LEFT JOIN (SELECT 2 id, 'salesperson' name ) salesperson
ON porder. salesperson_id =salesperson.id
Note: if you have more duplicate names - you need to alias all of them too

Joining two tables and getting values

I have two config tables. The structure is as below:
Table 1: Client_Config
id, name, value, type, description
Table 2: App_Config
name, value, type, description
I want to get name and value from Client_config table where id = #id.
I also want to get name and values from App_config for rows where there are no entries(matched with name) in client_config. Values for the same name can be different in both the tables.
eg:
Values in Client_Config
1, testName, testValue, testType, testDescription
1, testName1, testValue1, testType1, testDescription1
1, testName2, testValue2, testType2, testDescription2
Values in App_Config
testName, testValue1, testType, testDescription
testName1, testValue1, testType1, testDescription1
testName2, testValue2, testType2, testDescription2
testName3, testValue3, testType3, testDescription3
In the result set I need the following rows:
1, testName, testValue, testType, testDescription
1, testName1, testValue1, testType1, testDescription1
1, testName2, testValue2, testType2, testDescription2
NULL, testName3, testValue3, testType3, testDescription3
You can try a query like below
select
c.id, a.name, a.value, a.type, a.description
from App_Config a
left join
(
select * from Client_Config where id=#id
)c
on c.name=a.name
Explanation: We need all rows from app_config and corresponding id from client_config. So we do a **LEFT JOIN** from A to C. The C result set however must contain rows from a particular #id only so we sneak in a WHERE clause in the C set
Sql fiddle demo link : http://sqlfiddle.com/#!6/44659/4
You can do it using a left join:
SELECT t.id, s.name, s.value, s.type, s.description
FROM App_Config s
LEFT JOIN Client_Config t
ON(t.name = s.name and t.id = #id)
You can do it using a UNION ALL operation:
DECLARE #id INT = 1
SELECT id, name, value, type, description
FROM Client_Config
WHERE id = #id
UNION ALL
SELECT NULL, name, value, type, description
FROM App_Config AS ac
WHERE NOT EXISTS (SELECT 1
FROM Client_Config AS cc
WHERE cc.name = ac.name AND cc.id = #id)
Demo here
With a Left Join you get all the rows from the left table and all the corresponding rows from the right table. If there is no matching information, then the columns of the right table will be NULL.
Take a look at this useful diagram:
SQL Join Diagrams
In particular, your query can be something like this:
SELECT c.id, a.name, a.value, a.type, a.description
FROM App_Config a
LEFT JOIN Client_Config c
ON c.name = a.name
WHERE c.id = #id

Select multiple column query for view by using where clause?

How to get display id and name from a table into view. Where display id select by using where clause, upto now I am select only display id but now I want to select name also from same table.
old table was like this.
SELECT id,
(SELECT displayid
FROM quickpay12.q_sponsortrack AS Q_SponsorTrack_1
WHERE ( f1.transferto = f1.id )) AS TransferTo,
(SELECT displayid
FROM quickpay12.q_sponsortrack AS Q_SponsorTrack
WHERE ( f1.transferby = f1.id )) AS TransferBy,
descid,
credit,
debit,
description,
vdate,
balance,
wallettype,
sno
FROM quickpay12.f_transactionsummary_employee AS f1
Try following query to return all columns from all tables :
SELECT f1.* ,
Q_SponsorTrack_1.* ,
Q_SponsorTrack.*
FROM quickpay12.f_transactionsummary_employee AS f1
LEFT JOIN quickpay12.q_sponsortrack AS Q_SponsorTrack_1 ON f1.transferto = Q_SponsorTrack_1.id
LEFT JOIN quickpay12.q_sponsortrack AS Q_SponsorTrack ON f1.transferby = Q_SponsorTrack.id