Selecting specific cells from multiple tables - sql

I am trying to select specific cells from 3 different tables.
I have 3 different queries but whenever I run them it crashes a while and I was wondering if maybe I could combine them into one query.
SELECT * FROM INFM_DALI_BBM_CSC2.MARA_BBM
WHERE MANDT = '011'
AND MTART IN ('HALB','FERT')
AND "/RB04/YERZKENNZ" in ('EZ','BG','TS')
AND LOGSYS in ('SAPP72011', 'SAPPOE011');
SELECT * FROM INFM_DALI_BBM_CSC2.MARC_BBM
WHERE MANDT = '011'
AND BESKZ IN ('E','F')
AND WERKS in ('8640','864W','E499')
AND LOGSYS in ('SAPP72011', 'SAPPOE011');
SELECT * FROM INFM_DALI_BBM_CSC2.MBEW_BBM
WHERE MANDT = '011'
AND BKLAS IN ('7900','7920')
AND LOGSYS in ('SAPP72011', 'SAPPOE011');
The table should get the values that are on this table.
https://drive.google.com/file/d/1TSFJbpBsPJ5ZG61ULX6WumdNt1DUPJXO/view?usp=sharing

Consider this :
SELECT * FROM INFM_DALI_BBM_CSC2.MARA_BBM
WHERE MANDT = '011'
AND LOGSYS IN ('SAPP72011', 'SAPPOE011')
AND ( ( MTART IN ('HALB','FERT') AND "/RB04/YERZKENNZ" IN ('EZ','BG','TS') ) OR
( BESKZ IN ('E','F') AND WERKS IN ('8640','864W','E499') ) OR
( BKLAS IN ('7900','7920') ) )

Related

How to transform columns to rows in oracle sql

I have a table having below data , total 8 rows here sample for 3 rows -
now I transformed the query using case statement to this using below query -
select
case when entity ='PRODUCT' then prd_table_main end P_main_prd ,
case when entity ='PRODUCT' then prd_table_sec end P_sec_prd,
case when entity ='CUSTOMER' then cus_table_main end P_main_cus ,
case when entity ='CUSTOMER' then cus_table_sec end p_sec_cus,
case when entity ='PROFIT' then prof_table_main end p_main_prof ,
case when entity ='PROFIT' then prof_table_sec end p_sec_prof
from (
select * from above table);
Now I want to have the o/p as in one row removing all the nulls. Basically I want to create a cursor and pass the value of tables to be used in the procedure as p_main_prd or p_sec_prd or the remaining ones as the requirement.
You are almost there, you just need to aggeregate:
select MAX( case when entity = 'product' then table1 end ) AS P_main_prd,
MAX( case when entity = 'product' then table2 end ) AS P_sec_prd,
MAX( case when entity = 'customer' then table1 end ) AS P_main_cus,
MAX( case when entity = 'customer' then table2 end ) AS p_sec_cus,
MAX( case when entity = 'profit' then table1 end ) AS p_main_prof,
MAX( case when entity = 'profit' then table2 end ) AS p_sec_prof
from table_name;
or use PIVOT:
SELECT prd_p_main AS p_main_prd,
prd_p_sec AS p_sec_prd,
cus_p_main AS p_main_cus,
cus_p_sec AS p_sec_cus,
prof_p_main AS p_main_prof,
prof_p_sec AS p_sec_prof
FROM table_name
PIVOT (
MAX( table1 ) AS p_main,
MAX( table2 ) AS p_sec
FOR entity IN (
'product' AS prd,
'customer' AS cus,
'profit' AS prof
)
)
Which, for the sample data:
CREATE TABLE table_name ( entity, table1, table2 ) AS
SELECT 'product', 'prd_table_main', 'prd_table_sec' FROM DUAL UNION ALL
SELECT 'customer', 'cus_table_main', 'cus_table_sec' FROM DUAL UNION ALL
SELECT 'profit', 'prof_table_main', 'prof_table_sec' FROM DUAL
Outputs:
P_MAIN_PRD
P_SEC_PRD
P_MAIN_CUS
P_SEC_CUS
P_MAIN_PROF
P_SEC_PROF
prd_table_main
prd_table_sec
cus_table_main
cus_table_sec
prof_table_main
prof_table_sec
db<>fiddle here
Maybe you can try UNPIVOT. I'm not an expert on this, so I can only help you by giving you directions. Check this out, probably this will help you out, or at least show you another way:
Oracle Unpivot

Combining Columns from different tables

I've write a SQL code to combine several columns from different tables.
SELECT *
FROM
(
SELECT PD_BARCODE
FROM docsadm.PD_BARCODE
WHERE SYSTEM_ID = 11660081
) t,
(
SELECT A_JAHRE
FROM docsadm.A_PD_DATENSCHUTZ
WHERE system_ID = 2066
) t2,
(
SELECT PD_PART_NAME
FROM docsadm.PD_FILE_PART
WHERE system_id = 11660082
) t3;
code works fine but if one of my where clause is not found in a table,the result is null even the other columns have value. How you can solve this problem?
It looks like you are doing a cross join between the three subquery tables. This would probably only yield output which makes sense if each subquery return a single value. I might suggest instead that you use a UNION ALL here:
SELECT ISNULL(PD_BARCODE, 'NA' AS value
FROM docsadm.PD_BARCODE WHERE SYSTEM_ID = 11660081
UNION ALL
SELECT ISNULL(A_JAHRE, 'NA')
FROM docsadm.A_PD_DATENSCHUTZ WHERE system_ID = 2066
UNION ALL
SELECT ISULL(PD_PART_NAME, 'NA')
FROM docsadm.PD_FILE_PART WHERE system_id = 11660082
The above union query might require a slight modification if the three columns being select don't all have the same type (which I assume to be varchar in my query).
If you really need these three points of data as separate columns, then you can just include the three subqueries as items in an outer select:
SELECT
(SELECT ISNULL(PD_BARCODE, 'NA')
FROM docsadm.PD_BARCODE WHERE SYSTEM_ID = 11660081) AS PD_BARCODE,
(SELECT ISNULL(A_JAHRE, 'NA')
FROM docsadm.A_PD_DATENSCHUTZ WHERE system_ID = 2066) AS A_JAHRE,
(SELECT ISNULL(PD_PART_NAME, 'NA')
FROM docsadm.PD_FILE_PART WHERE system_id = 11660082) AS PD_PART_NAME;
Note that as the above is written we simply including the subqueries as values in the select statement. But as you wrote your original query, you are joining the subqueries as separate tables.
Here is Query.
You can replace the word 'empty' by your required word or value
SELECT isnull(
(
SELECT PD_BARCODE
FROM docsadm.PD_BARCODE
WHERE SYSTEM_ID = 11660081
), 'Empty') AS PD_BARCODE,
isnull(
(
SELECT A_JAHRE
FROM docsadm.A_PD_DATENSCHUTZ
WHERE system_ID = 2066
), 'Empty') AS A_JAHRE,
isnull(
(
SELECT PD_PART_NAME
FROM docsadm.PD_FILE_PART
WHERE system_id = 11660082
), 'Empty') AS PD_PART_NAME;
This is a special case since you would be getting only one value per query of yours which you are trying to put up as column. In this case, you can use SQL PIVOT clause with UNION ALL of your queries like shown below. MIN can be used for aggregation in this case.
This would mean, you can get your data row-wise as you like, even for multiple different fields and then pivot it into columns in one go.
SELECT * FROM
(
SELECT 'PD_BARCODE' as KeyItem, PD_BARCODE Name from docsadm.PD_BARCODE
where SYSTEM_ID=11660081
UNION ALL
SELECT 'A_JAHRE', A_JAHRE from docsadm.A_PD_DATENSCHUTZ
where system_ID=2066
UNION ALL
select 'PD_PART_NAME', PD_PART_NAME from docsadm.PD_FILE_PART
where system_id=11660082
) VTABLE
PIVOT(MIN(Name)
FOR KeyItem IN ([PD_BARCODE], [A_JAHRE], [PD_PART_NAME])) as pivotData;

How to merge two columns from CASE STATEMENT of DIFFERENT CONDITION

My expected result should be like
----invoiceNo----
T17080003,INV14080011
But right now, I've come up with following query.
SELECT AccountDoc.jobCode,AccountDoc.shipmentSyskey,AccountDoc.docType,
CASE AccountDoc.docType
WHEN 'M' THEN
JobInvoice.invoiceNo
WHEN 'I' THEN
(STUFF((SELECT ', ' + RTRIM(CAST(AccountDoc.docNo AS VARCHAR(20)))
FROM AccountDoc LEFT OUTER JOIN JobInvoice
ON AccountDoc.principalCode = JobInvoice.principalCode AND
AccountDoc.jobCode = JobInvoice.jobCode
WHERE (AccountDoc.isCancelledByCN = 0)
AND (AccountDoc.docType = 'I')
AND (AccountDoc.jobCode = #jobCode)
AND (AccountDoc.shipmentSyskey = #shipmentSyskey)
AND (AccountDoc.principalCode = #principalCode) FOR XML
PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' '))
END AS invoiceNo
FROM AccountDoc LEFT OUTER JOIN JobInvoice
ON JobInvoice.principalCode = AccountDoc.principalCode AND
JobInvoice.jobCode = AccountDoc.jobCode
WHERE (AccountDoc.jobCode = #jobCode)
AND (AccountDoc.isCancelledByCN = 0)
AND (AccountDoc.shipmentSyskey = #shipmentSyskey)
AND (AccountDoc.principalCode = #principalCode)
OUTPUT:
----invoiceNo----
T17080003
INV14080011
Explanation:
I want to select docNo from table AccountDoc if AccountDoc.docType = I.
Or select invoiceNo from table JobInvoice if AccountDoc.docType = M.
The problem is what if under same jobCode there have 2 docType which are M and I, how I gonna display these 2 invoices?
You can achieve this by using CTE and FOR XML. below is the sample code i created using similar tables you have -
Create table #AccountDoc (
id int ,
docType char(1),
docNo varchar(10)
)
Create table #JobInvoice (
id int ,
invoiceNo varchar(10)
)
insert into #AccountDoc
select 1 , 'M' ,'M1234'
union all select 2 , 'M' ,'M2345'
union all select 3 , 'M' ,'M3456'
union all select 4 , 'I' ,'I1234'
union all select 5 , 'I' ,'I2345'
union all select 6 , 'I' ,'I3456'
insert into #JobInvoice
select 1 , 'INV1234'
union all select 2 , 'INV2345'
union all select 3 , 'INV3456'
select *
from #AccountDoc t1 left join #JobInvoice t2
on t1.id = t2.id
with cte as
(
select isnull( case t1.docType WHEN 'M' THEN t2.invoiceNo WHEN 'I' then
t1.docNo end ,'') invoiceNo
from #AccountDoc t1 left join #JobInvoice t2
on t1.id = t2.id )
select invoiceNo + ',' from cte For XML PATH ('')
You need to pivot your data if you have situations where there are two rows, and you want two columns. Your sql is a bit messy, particularly the bit where you put an entire select statement inside a case when in the select part of another query. These two queries are virtually the same, you should look for a more optimal way of writing them. However, you can wrap your entire sql in the following:
select
Jobcode, shipmentsyskey, [M],[I]
from(
--YOUR ENTIRE SQL GOES HERE BETWEEN THESE BRACKETS. Do not alter anything else, just paste your entire sql here
) yoursql
pivot(
max(invoiceno)
for docType in([M],[I])
)pvt

How to create CTE which uses another CTE as the data to further limit?

I have searched this question here but couldn't find it, please redirect me if we already have it on the site.
I'm looking for a way to create CTE which uses another CTE as the data to further limit. I have a CTE which creates a report for me , but I would like to narrow this report with another input using the existing CTE.
I hope my question is clear.
You can chain 2 (or more) CTE's together.
For example
with ObjectsWithA as
(
select * from sys.objects
where name like '%A%'
),
ObjectsWithALessThan100 as
(
select * from ObjectsWithA
where object_id < 100
)
select * from ObjectsWithALessThan100;
Or the same example, with more "spelled out" names/aliases:
with ObjectsWithA (MyObjectId , MyObjectName) as
(
select object_id as MyObjIdAlias , name as MyNameAlias
from sys.objects
where name like '%A%'
),
ObjectsWithALessThan100 as
(
select * from ObjectsWithA theOtherCte
where theOtherCte.MyObjectId < 100
)
select lessThan100Alias.MyObjectId , lessThan100Alias.MyObjectName
from ObjectsWithALessThan100 lessThan100Alias
order by lessThan100Alias.MyObjectName;
A CTE can refer to previous CTEs:
with report as (
<your query here>
),
reportLimited as (
select *
from report
where foo = #bar
)
select *
from reportLimited
The only rule is that the references have to be sequential. No forward references.
Sure, just reference the CTE directly:
WITH Source As
(
SELECT * FROM AllData
),
Filtered AS
(
SELECT * FROM Source WHERE ID = 4
)
SELECT * FROM Filtered
WITH
Source ---------1---------
As
(
SELECT * FROM emp
),
destination----2----------
AS
(
SELECT *
FROM Source
WHERE E_id = 4
)
SELECT * FROM destination

How to check existence of data in a table from a where clause in sql server 2008?

Suppose I have a table with columns user_id, name and the table contains data like this:
user_id name
------- -----
sou souhardya
cha chanchal
swa swapan
ari arindam
ran ranadeep
If I want to know these users (sou, cha, ana, agn, swa) exists in this table or not then I want output like this:
user_id it exists or not
------- -----------------
sou y
cha y
ana n
agn n
swa y
As ana and aga do not exist in the table it must show "n" (like the above output).
Assuming your existing checklist is not on the database, you will have to assemble a query containing those. There are many ways of doing it. Using CTEs, it would look like this:
with cte as
(
select 'sou' user_id
union all
select 'cha'
union all
select 'ana'
union all
select 'agn'
union all
select 'swa'
)
select
cte.user_id,
case when yt.user_id is null then 'n' else 'y' end
from cte
left join YourTable yt on cte.user_id = yt.user_id
This also assumes user_id is unique.
Here is the SQLFiddle with the proof of concept: http://sqlfiddle.com/#!3/e023a0/4
Assuming you're just testing this manually:
DECLARE #Users TABLE
(
[user_id] VARCHAR(50)
)
INSERT INTO #Users
SELECT 'sou'
UNION SELECT 'cha'
UNION SELECT 'ana'
UNION SELECT 'agn'
UNION SELECT 'swa'
SELECT a.[user_id]
, [name]
, CASE
WHEN b.[user_id] IS NULL THEN 'N'
ELSE 'Y'
END AS [exists_or_not]
FROM [your_table] a
LEFT JOIN #Users b
ON a.[user_id] = b.[user_id]
You didn't provide quite enough information to provide a working example, but this should get you close:
select tbl1.user_id, case tbl2.user_id is null then 'n' else 'y' end
from tbl1 left outer join tbl2 on tbl1.user_id = tbl2.user_id
;with usersToCheck as
(
select 'sou' as userid
union select 'cha'
union select 'ana'
union select 'agn'
union select 'swa'
)
select utc.userid,
(case when exists ( select * from usersTable as ut where ut.user_id = utc.userid) then 'y' else 'n' end)
from usersToCheck as utc