set a variable in outer apply statement sql - sql

I want to get one row in Outer apply statement for one of task Id, but SQL be angry me in outer apply statement with red line :) Any ideas ?
declare #OwnerUserIDs as Nvarchar(max)
select bt.*
,cu.NAME+' '+cu.SURNAME as OwnerUserName
,cu2.NAME+' '+cu2.SURNAME as CreatedUserName
,T.Data
from Business_Tasks(nolock) bt
left join CommmerceCoreReleaseV1..CORE_USERS(nolock) cu on cu.USERID=bt.OwnerUserID
left join CommmerceCoreReleaseV1..CORE_USERS(nolock) cu2 on cu2.USERID=bt.CreatedUserID
outer apply
(
SELECT #OwnerUserIDs = Data from ( select COALESCE(#OwnerUserIDs + ';', '') + convert(nvarchar,bto.ownerUserID) as Data from Business_TasksOwner(nolock) bto where bto.TaskID=13)
) T
where bt.IsActive=1 and bt.ID=13
Answer
Hi, I found the answer, i changed inside of outer apply statement :
select bt.*
,cu.NAME+' '+cu.SURNAME as OwnerUserName
,cu2.NAME+' '+cu2.SURNAME as CreatedUserName
,T.OwnerUserIDs
from Business_Tasks(nolock) bt
left join CommmerceCoreReleaseV1..CORE_USERS(nolock) cu on cu.USERID=bt.OwnerUserID
left join CommmerceCoreReleaseV1..CORE_USERS(nolock) cu2 on cu2.USERID=bt.CreatedUserID
outer apply
(
select STUFF((SELECT ';'+ convert(nvarchar,bto.OwnerUserID)
FROM Business_TasksOwner(nolock) bto
where bto.TaskID=bt.ID
FOR XML PATH('')), 1, 1, '') AS OwnerUserIDs
) T
where bt.IsActive=1 and bt.ID=13

Okay, there are a few issues with your query as it stands:
you need to add an alias name to your inner query, the one that starts "SELECT COALESCE...", i.e. put a letter, say X, after "bto.TaskId = 13)".
you can't set your variable to the results of this sub-query the way you have, if you remove the "#OwnerUserIDs = " bit then your query should compile;
I don't understand what your OUTER APPLY is trying to achieve, surely it will just return the same results for every row returned, i.e. where TaskId = 13? Maybe this should be referring to the main query in some way?
If you want to set the #OwnerUserIDs to be the concatenated results of the OwnerUserIDs then you need to use a different mechanism, either a recursive CTE or XML PATH query would work.
I would try to rewrite your query for you but I am not sure what you are trying to achieve here. I guess you want to end up with a list of User Ids in #OwnerUserIDs but I'm not sure what the rules should be...

Related

Replace row with Column Data in Sql Server

I have a table with some data and I was trying to Replace the Column with Row.
SELECT Handset_UID, [IMEI_NO_1] AS [IMEI #1],[IMEI_NO_2] AS [IMEI #2],
Isnull(Convert(varchar,Mfg_Date,106),'Not Found') as [Mfg. Date]
FROM stock.Handset a
join Stock.Model b
on a.Model_ID = b.Model_ID
JOIN Stock.Brand C
ON A.Brand_ID = C.Brand_ID
where a.Handset_UID = 'GFI13508637275434'
The above Query gives me the result in one single row data.
But I want the Result in below format
I have tried the Pivot Operator using Derived Column but got confused during implementation.
Please help to get the correct query.
Assuming that you are running SQL Server, as the syntax suggests, you can unpivot with cross apply:
select x.col, x.val
from stock.handset h
inner join stock.model m on h.model_id = m.model_id
inner join stock.brand b on on h.brand_id = b.brand_id
cross apply (values
('handset_uid', handset_uid),
('IMEI #1', imei_no_1),
('IMEI #2', imei_no_2),
('Mfg.Date', convert(varchar, Mfg_Date, 106), 'Not Found')
) x(col, val)
where h.handset_uid = 'gfi13508637275434'
Side notes:
meaningful table aliases make the query easier to read and write
your query has many columns that are not qualified with the alias of the table they belong to, which makes your query rather unclear about the underlying structure; I would strongly recommend that you qualify all columns in the query

Select inside select not working properly and shows error

I have 2 tables:
t_orderPayment with n_id,n_order,n_paytype AND
t_paytype with n_ID , str_desc
My Query is:
SELECT t_OrderPayment.n_order ,
t_OrderPayment.n_paytype = (select t_paytype.str_desc as n_paytype from t_PayType, t_orderpayment where t_OrderPayment.n_PayType = t_PayType.n_ID)
FROM t_OrderPayment
WHERE (((t_OrderPayment.n_PaymentStatus)<>-7)) ;
It returns error
"At most one record can be returned by this subquery"
I tried to set it with MAX and TOP 1 like n_paytype = (select max(t_paytype.str_desc) but shows me error Expr1001
Str.desc have only text values and this could be the reason. May be INNER JOIN can help me somehow?
It looks like you've accidentally made a cross join. You don't need a second reference to the t_OrderPayment table inside the subquery - try removing that (but leaving the where clause as that's what will link it to the outer query). It looks like the whole subquery could be removed and turned into a join though...
SELECT t_OrderPayment.n_order,
t_paytype.str_desc AS n_paytype
FROM t_OrderPayment
INNER JOIN t_PayType
ON t_OrderPayment.n_PayType = t_PayType.n_ID
WHERE t_OrderPayment.n_PaymentStatus <> -7;
SELECT t_OrderPayment.n_order,
t_paytype.str_desc AS n_paytype
FROM t_OrderPayment, t_PayType
WHERE t_OrderPayment.n_PayType = t_PayType.n_ID AND
t_OrderPayment.n_PaymentStatus <> -7;

SQL Developer AND OR Statements

Got a task at my job to get several fields from different tables into one sheet, using SQL Developer. Im a noob to SQL, however managed to build something. Taking a look at my output learns me that the restrictions I built in do not work. Short description below. Can someone please help me?! In my output I still see values other than 1006 in the ATINN field, values other tham Empty in the BWTAR field.. What am I doing wrong?
5 tables linked together
Restriction on Users (DMSTRAATL, etc)
Restriction on Productgroup (006*, etc)
Restriction on some individual products
Restriction on product type (HERB, etc)
Restriction on specific data field (All products should have atinn = 1006)
Restiction on specific data field (all products should have bwtar = empty)
SELECT
dmssap.mara.matnr, dmssap.mara.mtart, dmssap.mara.matkl,
dmssap.mara.ersda, dmssap.mara.ernam, dmssap.mara.bismt,
dmssap.marc.werks, dmssap.inob.cuobj,
LPAD(INOB.CUOBJ, 18, '0') AS CUOBJ_18, dmssap.ZMM_MATNR_MPO.matnr, dmssap.ZMM_MATNR_MPO.pname,
dmssap.ZMM_MATNR_MPO.stat, dmssap.mbew.bwkey, dmssap.mbew.bklas,
dmssap.mbew.bwtar, dmssap.mbew.vprsv, dmssap.mbew.bwtty, dmssap.mbew.verpr,
dmssap.mbew.stprs, dmssap.ZMM_MATNR_MPO.matnr, dmssap.ZMM_MATNR_MPO.pname,
dmssap.ZMM_MATNR_MPO.stat, dmssap.ausp.atinn, dmssap.ausp.atwrt
FROM dmssap.mara
LEFT OUTER JOIN dmssap.marc
ON (dmssap.marc.matnr) = (dmssap.mara.matnr)
LEFT OUTER JOIN dmssap.ZMM_MATNR_MPO
ON (dmssap.ZMM_MATNR_MPO.matnr) = (dmssap.mara.matnr)
LEFT OUTER JOIN dmssap.mbew
ON CONCAT(dmssap.mbew.matnr, dmssap.mbew.bwkey) = CONCAT(dmssap.marc.matnr, dmssap.marc.werks)
LEFT OUTER JOIN dmssap.inob
ON (dmssap.inob.objek) = (dmssap.mara.matnr)
LEFT OUTER JOIN dmssap.ausp
ON dmssap.ausp.objek = LPAD(INOB.CUOBJ, 18, '0')
WHERE (dmssap.mara.ernam) IN (
'DMSTRAATL', 'V0342628', 'V0343809',
'V0336003', 'V0009830', 'V0309577', 'V0010144'
)
AND (dmssap.mara.matkl) IN (
'006*', '007120', '007130', '007140', '007170',
'007180', '007210', '007220', '007230',
'007250', '007270', '007280', '007290',
'007300', '007320', '007340',
'007370', '007380', '007400', '007420'
)
OR (dmssap.mara.matnr) IN (
'000000010001767697', '000000010001870117', '000000010001870116', '000000010001870115',
'000000010001870114', '000000010001870113', '000000010001870112'
)
AND (dmssap.mara.mtart) IN ('HERB', 'HALB', 'ZSTP')
AND (dmssap.ausp.atinn) = '1006'
AND (dmssap.mbew.bwtar) IS NULL;
AND operator has an higher precedence order than OR . to make your query easily readable use braces () around filter clauses.
Let's say you want to select records which have certain values in dmssap.mara.matkl or certain values in dmssap.mara.matnr then you can use braces between these blocks to be precise as shown below.
AND (
(dmssap.mara.matkl) IN (
'006*', '007120', '007130', '007140', '007170',
'007180', '007210', '007220', '007230',
'007250', '007270', '007280', '007290',
'007300', '007320', '007340',
'007370', '007380', '007400', '007420'
)
OR (dmssap.mara.matnr) IN (
'000000010001767697', '000000010001870117', '000000010001870116', '000000010001870115',
'000000010001870114', '000000010001870113', '000000010001870112'
)
)
WHERE (dmssap.mara.ernam) IN (
'DMSTRAATL', 'V0342628', 'V0343809',
'V0336003', 'V0009830', 'V0309577', 'V0010144'
)
AND (dmssap.mara.matkl) IN (
'006*', '007120', '007130', '007140', '007170',
'007180', '007210', '007220', '007230',
'007250', '007270', '007280', '007290',
'007300', '007320', '007340',
'007370', '007380', '007400', '007420'
)
OR (dmssap.mara.matnr) IN (
'000000010001767697', '000000010001870117', '000000010001870116', '000000010001870115',
'000000010001870114', '000000010001870113', '000000010001870112'
)
AND (dmssap.mara.mtart) IN ('HERB', 'HALB', 'ZSTP')
AND (dmssap.ausp.atinn) = '1006'
AND (dmssap.mbew.bwtar) IS NULL;
The crux is in your WHERE statement. The evaluation order for keywords in the WHERE statement is NOT -> AND -> OR
What you seem to want is this instead:
WHERE (dmssap.mara.ernam) IN (
'DMSTRAATL', 'V0342628', 'V0343809',
'V0336003', 'V0009830', 'V0309577', 'V0010144'
)
AND (dmssap.mara.matkl) IN ((
'006*', '007120', '007130', '007140', '007170',
'007180', '007210', '007220', '007230',
'007250', '007270', '007280', '007290',
'007300', '007320', '007340',
'007370', '007380', '007400', '007420'
)
OR (dmssap.mara.matnr) IN (
'000000010001767697', '000000010001870117', '000000010001870116', '000000010001870115',
'000000010001870114', '000000010001870113', '000000010001870112'
))
AND (dmssap.mara.mtart) IN ('HERB', 'HALB', 'ZSTP')
AND (dmssap.ausp.atinn) = '1006'
AND (dmssap.mbew.bwtar) IS NULL;
Notice the two extra brackets around the OR on the AND

How to use split.item in SQL, spliting cols by commas

I'm getting the error:
"The multi-part identifier "split.item" could not be bound."
Pretty much I'm going to make a third table with each individual person this is just an example:
SELECT
split.item as memberID
FROM
tics T
JOIN
mem M
ON
m.memberId = split.item
CROSS APPLY
dbo.Splitstring(t.Resources,',') AS split
You have the join in wrong order, you can't refer to something that comes later in the SQL, in this case "m.memberId = split.item" since split is the next item you're adding there. The correct way to do this is:
SELECT
split.item as memberID
FROM
tics T
CROSS APPLY dbo.Splitstring(t.Resources,',') AS split
JOIN mem M ON m.memberId = split.item

Access Left Join not working properly

In access I wrote this query:
Select
I.sysid, I.MemberNumber, I.Date, I.Distributer,
F.MemberNumber as FMember, F.Date as FDate, I.Distributer as FDistributer
From Initial as I
Left Join Final as F ON
I.MemberNumber=F.MemberNumber and
I.Distributer=F.Distributer and
I.Date>=F.Date-14 and
I.Date<=F.Date+14;
But the left join is not behavior properly. There are fewer rows in this table then there are in Initial... but it should be keeping ALL rows from initial, because I am using a left join, right? I have found several rows in initial (like sysid=7, which is Initial's key) that just isn't coming into this table.
It may have to do with your AND logic. Add some ( ) parenthesis to this to include it all like so:
Select
I.sysid, I.MemberNumber, I.Date, I.Distributer,
F.MemberNumber as FMember, F.Date as FDate, I.Distributer as FDistributer
From Initial as I
Left Join Final as F ON
(I.MemberNumber=F.MemberNumber and
I.Distributer=F.Distributer and
(I.Date>=F.Date-14) and
(I.Date<=F.Date+14));
Also I think there is a dateadd function, I'd use that instead of + / -.
If you're in the Query Designer, make sure all the filters are cleared. I've built your tables and sql and can't reproduce your error.
SELECT I.sysid
, I.MemberNumber
, I.Dated
, I.Distributer
, F.MemberNumber
, F.Dated AS FDated
, F.Distributer AS FDistributer
FROM Initial AS I
LEFT JOIN Final AS F
ON I.Distributer = F.Distributer
AND I.MemberNumber = F.MemberNumber
AND I.Dated>=F.Dated-14
AND I.Dated<=F.Dated+14;
Try adding additional fields to the original table and using update queries to add extra columns. This way you can be sure you won't drop any columns.