Data from same table with different where clauses into same view - sql-server

I'm trying to get two kinds of data from same table into a view. I tried adding a join to same table with a different alias but it caused some null values.
I want the datatable as a single row , if possible. I know this can be done with union operator too but it causes multiple rows.
Here is my select
SELECT
COUNT(PO.OrderID) AS MerkezOnaySiparisAdet, SUM(PO.TotalPromotionPrice) AS MerkezOnayToplamSatis,
COUNT(PO2.OrderID) AS DepoOnaySiparişAdet, SUM(PO2.TotalPromotionPrice) AS DepoOnayToplamSatis
FROM PrmOrder PO
LEFT JOIN PrmOrder PO2 ON PO.OrderID = PO2.OrderId AND (PO2.OrderStatusID != 1 AND PO2.IsOrderApproved = 1 AND PO2.IsInventoryApproved = 0 AND (PO2.OrderStatusID = 2 OR PO2.OrderStatusID = 3))
WHERE 1=1
AND PO.OrderStatusID != 1
AND PO.IsOrderApproved = 0
AND (PO.OrderStatusID = 2 OR PO.OrderStatusID = 3)
What is the correct way of doing this?

Maybe, this isn't the best way, but you can use subquery. For example
SELECT
A1.Sum1,
A2.Sum2 FROM
(
SELECT
SUM(sod.OrderQty) sum1,
1 joinnumber
FROM
Sales.SalesOrderDetail sod
WHERE
sod.ProductID = 772
) AS A1
JOIN (
SELECT
SUM(sod.OrderQty) sum2,
1 joinnumber
FROM
Sales.SalesOrderDetail sod
WHERE
sod.ProductID = 773
) AS A2
ON A1.joinnumber = A2.joinnumber

Related

Avoid table function in where clause?

I have added table function in the where clause.
select cmp_id, acno_code, sl_type, sl_code, 0 op_Dr, 0 op_cr, 0 tr_Dr, sum(amount) tr_Cr
from vf_finance
where cmp_id =#cmp_id1
and unitcode in (select * from UTILfn_Split( #unit_code,',') )
and stat_code in ('AT','PR' )
--and pc_code in (select * from UTILfn_Split( #sba,',') )
AND DOC_dT >=convert(datetime,#from_date,103) and doc_Dt <= convert(datetime,#to_date,103)
and amount < 0
GROUP BY cmp_id, acno_code, sl_type, sl_code
) as gl
inner join ps_Accmas acc on acc.cmp_id = gl.cmp_id and acc.acno_Code = gl.acno_code
inner join ps_owner o on gl.cmp_id = o.cmp_id
left outer join view_sl_code sl on gl.cmp_id = sl.cmp_id and gl.sl_type = sl.sl_type and gl.sl_Code = sl.sl_Code
inner join ps_slType slt on gl.cmp_id = slt.cmp_id and gl.sl_Type = slt.sl_type
where sl.sl_type in (select * from UTILfn_Split( #sl_type,',') )
and acc.acno_code in(select * from UTILfn_Split( #facno_code,',') )
group by gl.cmp_id, gl.acno_code,gl.sl_code,gl.sl_type,slt.sl_DEsc,acc.acno_DEsc, sl.sl_DEsc, o.owner_name
order by gl.cmp_id, gl.acno_code,gl.sl_code,gl.sl_type
Can anyone please suggest how I can avoid function in where clause?
You may try this. There are some issues in this existing query which I'll point first
First unitcode in (select * from UTILfn_Split( #unit_code,',') here you must use one column name instead of *, although i don't know about your function UTILfn_Split but still mention column name is preferable.
for your query you may use inner join instead of in with function having return type table.
Instead of
sl.sl_type in (select * from UTILfn_Split( #sl_type,',') )
You may try this
yourtble as sl inner join
(select value from UTILfn_Split( #sl_type,',') as t2
on sl.sl_type = t2.[value] ---- here column name with t2 depends on your function,
---what table structure is returning, in your case it is [value]

GROUP BY total order quantity

we're trying to make our table add together all values in column 2 (QtyComp - an expression column of qtyorder * totalqty basically), where they have the same ItemNo (column 1).
So, we currently get the below:
ItemNo QtyComp
7441 3
7441 1
7441 5
What we want is it to see the SUM of the column QTYComp to give this result:
ItemNo QtyCom
7441 9
Our code is below; I've bolded the part that we need it to sum the results of:
SELECT TOP (100) PERCENT ItemSpecs_2.itemno,
workorderdetails.qtycomplete *
ItemSpecFullStruc_2.totalqtyperroot AS QtyComp
FROM dbo.workorderdetails AS WorkOrderDetails
INNER JOIN dbo.itemspecfullstruc AS ItemSpecFullStruc_2
ON ItemSpecFullStruc_2.rootitemspecid =
workorderdetails.itemspecid
INNER JOIN dbo.itemspecs AS ItemSpecs_2
ON ItemSpecs_2.itemspecid = ItemSpecFullStruc_2.childitemspecid
INNER JOIN dbo.workorder AS WorkOrder_1
ON WorkOrder_1.workorderid = workorderdetails.workorderid
LEFT OUTER JOIN dbo.tobescheduled_completed
ON WorkOrder_1.workorderid =
dbo.tobescheduled_completed.workorderid
WHERE ( workorderdetails.completed = 1 )
AND ( workorderdetails.compdate > Getdate() - 42 )
GROUP BY ItemSpecs_2.itemno,
workorderdetails.qtyordered,
ItemSpecFullStruc_2.totalqtyperroot,
workorderdetails.[lineno],
workorderdetails.qtycomplete,
workorderdetails.compdate,
workorderdetails.qtycomplete * ItemSpecFullStruc_2.totalqtyperroot
We would really appreciate some ideas!
Thanks,
Trish
If you want to sum these column, simply add a sum() syntax as follows:
SELECT TOP (100) PERCENT ItemSpecs_2.itemno,
sum(workorderdetails.qtycomplete *
ItemSpecFullStruc_2.totalqtyperroot) AS QtyComp
FROM dbo.workorderdetails AS WorkOrderDetails
INNER JOIN dbo.itemspecfullstruc AS ItemSpecFullStruc_2
ON ItemSpecFullStruc_2.rootitemspecid =
workorderdetails.itemspecid
INNER JOIN dbo.itemspecs AS ItemSpecs_2
ON ItemSpecs_2.itemspecid = ItemSpecFullStruc_2.childitemspecid
INNER JOIN dbo.workorder AS WorkOrder_1
ON WorkOrder_1.workorderid = workorderdetails.workorderid
LEFT OUTER JOIN dbo.tobescheduled_completed
ON WorkOrder_1.workorderid =
dbo.tobescheduled_completed.workorderid
WHERE ( workorderdetails.completed = 1 )
AND ( workorderdetails.compdate > Getdate() - 42 )
GROUP BY ItemSpecs_2.itemno,
workorderdetails.qtyordered,
ItemSpecFullStruc_2.totalqtyperroot,
workorderdetails.[lineno],
workorderdetails.qtycomplete,
workorderdetails.compdate
Also, you need to delete from group by that column.
For getting the desired result, set a GROUP BY only by ItemSpecs_2.itemno
assuming your current code gives you correct calculations, the lazy answer would be to write it as a CTE and then sum it, but this may result in sub optimal table scans - fine if it's just adhoc.
with mytemp as (
SELECT TOP (100) PERCENT ItemSpecs_2.itemno,
workorderdetails.qtycomplete *
ItemSpecFullStruc_2.totalqtyperroot AS QtyComp
FROM dbo.workorderdetails AS WorkOrderDetails
INNER JOIN dbo.itemspecfullstruc AS ItemSpecFullStruc_2
ON ItemSpecFullStruc_2.rootitemspecid =
workorderdetails.itemspecid
INNER JOIN dbo.itemspecs AS ItemSpecs_2
ON ItemSpecs_2.itemspecid = ItemSpecFullStruc_2.childitemspecid
INNER JOIN dbo.workorder AS WorkOrder_1
ON WorkOrder_1.workorderid = workorderdetails.workorderid
LEFT OUTER JOIN dbo.tobescheduled_completed
ON WorkOrder_1.workorderid =
dbo.tobescheduled_completed.workorderid
WHERE ( workorderdetails.completed = 1 )
AND ( workorderdetails.compdate > Getdate() - 42 )
GROUP BY ItemSpecs_2.itemno,
workorderdetails.qtyordered,
ItemSpecFullStruc_2.totalqtyperroot,
workorderdetails.[lineno],
workorderdetails.qtycomplete,
workorderdetails.compdate,
workorderdetails.qtycomplete * ItemSpecFullStruc_2.totalqtyperroot
)
select
itemno
,sum(QtyComp) as QtyComp
from mytemp
group by itemno

How to supply multiple values in between clause after where clause

SELECT
ROW_NUMBER() OVER (ORDER BY Vendor_PrimaryInfo.Vendor_ID ASC) AS RowNumber,
*
FROM
Unit_Table
INNER JOIN
Vendor_Base_Price ON Unit_Table.Unit_ID = Vendor_Base_Price.Unit_ID
INNER JOIN
Vendor_PrimaryInfo ON Vendor_Base_Price.Vendor_ID = Vendor_PrimaryInfo.Vendor_ID
INNER JOIN
Vendor_Registration ON Vendor_Base_Price.Vendor_ID = Vendor_Registration.Vendor_ID
AND Vendor_PrimaryInfo.Vendor_ID = Vendor_Registration.Vendor_ID
INNER JOIN
Category_Table ON Vendor_Registration.Category_ID = Category_Table.Category_ID
LEFT JOIN
Vendor_Value_Table ON Vendor_Registration.Vendor_ID = Vendor_Value_Table.Vendor_ID
LEFT JOIN
Feature_Table ON Vendor_Value_Table.Feature_ID = Feature_Table.Feature_ID
WHERE
Vendor_Registration.Category_ID = 5
AND Vendor_PrimaryInfo.City = 'City'
AND (value_text in ('sample value') or
(SELECT
CASE WHEN ISNUMERIC(value_text) = 1
THEN CAST(value_text AS INT)
ELSE -1
END) BETWEEN 0 AND 100)
As column has multiple values which may be text or may be int that's why I cast based on case. My question is: I just want to fetch the records either whose value is between 0 and 100 or value between 300 to 400 or value is like sample value.
I just want to place the condition after where clause and do not want to use column_name multiple time in between operator because these values are coming from url
Thanks in advance any help would be grateful.
You can try this way..
WHERE
Vendor_Registration.Category_ID = 5
AND Vendor_PrimaryInfo.City = 'City'
AND (value_text in ('sample value') or
(CASE WHEN (ISNUMERIC(value_text) = 1)
THEN CAST(value_text AS INT)
ELSE -1
END) BETWEEN 0 AND 100)

Grouping by ShopName Count Different type of Customer(membership)

We have a 2 tables
Table 1
Shop where we have shop details
ShopNo, ShopName
Table 2
Customer where we have all customer details
CustomerId, CustomerName, MembershipType, ShopId
what we are trying to query is
ShopName SilverMember GoldMember LifeMember
ABC 45 110 1
XYZ 90 0 10
DEF 10 10 7
Is there a way to make it possible
if in Linq well and good else only sql query will do thanks in advance
Regards
Moksha
Something like this should do the trick:
select s.ShopName,
count(c1.CustomerId) as 'SilverMember',
count(c2.CustomerId) as 'GoldMember',
count(c3.CustomerId) as 'LifeMember'
from Shop s
left outer join Customer c1 on c1.ShopId = s.ShopNo and c1.MembershipType = 'SilverMember'
left outer join Customer c2 on c2.ShopId = s.ShopNo and c2.MembershipType = 'GoldMember'
left outer join Customer c3 on c3.ShopId = s.ShopNo and c3.MembershipType = 'LifeMember'
group by s.ShopName
Assuming MembershipType contains the actual VARCHAR values SilverMember, GoldMember, and LifeMember, this should work in T-SQL:
SELECT
[ShopName], COUNT([SilverMember]) AS [SilverMember], COUNT([GoldMember]) AS [GoldMember], COUNT([LifeMember]) AS [LifeMember]
FROM
[Table1]
INNER JOIN [Table2]
ON [Table1].[ShopNo] = [Table2].[ShopId]
PIVOT
(
MAX([MembershipType])
FOR [MembershipType] IN ([SilverMember], [GoldMember], [LifeMember])
) AS [P]
GROUP BY
[ShopName]
Example on SQL Fiddle
If you want to use linq:
var query = from s in context.Shops
join c in context.Customers on s.ShopNo equals c.ShopId
group c by s.ShopName into g
select new
{
ShopName = g.Key,
SilverMember = g.Count(c => c.MembershipType == "SilverMember"),
GoldMember= g.Count(c => c.MembershipType == "GoldMember"),
LifeMember= g.Count(c => c.MembershipType == "LifeMember"),
};

Joining two queries horizontally

I wrote two queries below that produce one row of data each.
What is the best way to combine them such that I am LEFT with only a single row of data?
These are coming FROM two DISTINCT databases named : [ASN01] and [dsi_ASN_dsicx]
I have 70 pairs of databases like this but am showing only one for simplicity.
The fact that the three letter acronym ASN is common to both database names is no mistake and if needed can be a part of the solution.
Current Results:
Site, Elligence (header)
ASN, 100.00
Site, GP_Total (header)
ASN, 120.00
Desired results:
Site, GP_Total, Elligence (header)
ASN, 120.00, 100.00
SELECT 'ASN' AS Site ,
CASE SUM(perdblnc)
WHEN NULL THEN 0
ELSE -1 * SUM(PERDBLNC)
END AS GP_Total
FROM [ASN01].[dbo].[GL10110] T1
LEFT OUTER JOIN [ASN01].[dbo].[GL00105] T2 ON [T1].[ACTINDX] = [T2].[ACTINDX]
WHERE YEAR1 = 2012
AND PERIODID IN ( '2' )
AND ACTNUMST IN ( '4200-0000-C', '6940-0000-C', '6945-0000-C',
'6950-0000-C' )
SELECT 'ASN' AS [Site] ,
SUM(pi.amount) AS [Elligence]
FROM [dsi_ASN_dsicx].dbo.charge c
LEFT JOIN [dsi_ASN_dsicx].dbo.paymentitem pi ON c.idcharge = pi.chargeid
LEFT JOIN [dsi_ASN_dsicx].dbo.payment p ON pi.paymentid = p.idpayment
LEFT JOIN [dsi_ASN_dsicx].dbo.paymenttype pt ON p.paymenttypeid = pt.idpaymenttype
WHERE pi.amount != 0
AND pt.paymentmethod NOT IN ( '5', '7' )
AND pt.paymentmethod IS NOT NULL
AND p.sdate >= '20120201'
AND p.sdate <= '20120229'
WIthout going through and changing any of your queries, the easiest way would be to use temp tables using the "WITH" common_table_expression. Table1 and Table2 are temp tables created from your select statements. Therefore, we select table1 and join table2.
Let me know if there are any syntax problems, I don't have anything to test this on presently.
;With Table1 as (SELECT 'ASN' as Site, Case sum(perdblnc)
WHEN NULL THEN 0
ELSE -1*sum(PERDBLNC) END as GP_Total
FROM [ASN01].[dbo].[GL10110] T1
Left Outer Join [ASN01].[dbo].[GL00105] T2
ON [T1]. [ACTINDX]= [T2]. [ACTINDX]
WHERE YEAR1 = 2012
AND PERIODID in ('2')
AND ACTNUMST in ('4200-0000-C', '6940-0000-C', '6945-0000-C', '6950-0000-C'))
, Table2 as (SELECT
'ASN' as [Site],
SUM(pi.amount) as [Elligence]
FROM [dsi_ASN_dsicx].dbo.charge c
LEFT JOIN [dsi_ASN_dsicx].dbo.paymentitem pi on c.idcharge = pi.chargeid
LEFT JOIN [dsi_ASN_dsicx].dbo.payment p on pi.paymentid = p.idpayment
LEFT JOIN [dsi_ASN_dsicx].dbo.paymenttype pt on p.paymenttypeid = pt.idpaymenttype
WHERE pi.amount != 0
AND pt.paymentmethod not in ('5','7')
AND pt.paymentmethod is not null
AND p.sdate >='20120201' and p.sdate <= '20120229')
SELECT * FROM Table1
LEFT JOIN Table2 ON Table1.site = Table2.site
Hope this helps! Marks as answer if it is =)

Resources