SQL WHERE date partially field and partially predefined string - sql

For my project we are using MS SQL 2008. In an subquery i like to search in an WHERE clause to the last day of the current (in the SQL loop) year. It should be something like:
WHERE datefieldsubquery = currentyearparentquery+'-12-31 23:59:00'
But there is no output in the subquery while using this. When the query is for example:
WHERE datefieldsubquery = '2014-12-31 23:59:00'
the query returns an result. I like that '2014' is dynamically inherited from the parent query. Is that possible in SQL?
-- edit --
Both fields are datetime.
Real complete query:
SELECT factuurregel.[Internal costkind] AS code,
COUNT(factuurregel.[Internal costkind]) AS total,
YEAR(factuurregel.[Invoice date lease company]) AS maand,
(
SELECT COUNT(leasecontract.[Contract Ending Date]) AS autos
FROM [test$Lease Contract] AS leasecontract
WHERE (leasecontract.[Status] = '0' OR leasecontract.[Status] = '1')
AND YEAR(leasecontract.[Contract Activation Date]) <= YEAR(factuurregel.[Invoice date lease company])
AND (YEAR(leasecontract.[Contract Ending Date]) > YEAR(factuurregel.[Invoice date lease company])
OR leasecontract.[Contract Ending Date] = '1753-01-01 00:00:00')
) AS autos
FROM [test$Invoice line] AS factuurregel
LEFT JOIN [test$Lease Car] AS leasecar ON factuurregel.[License No_] = leasecar.[License No_]
WHERE factuurregel.[Internal costkind] >= '200'
AND factuurregel.[Internal costkind] < '300'
AND (leasecar.[Licence Type] = 1 OR leasecar.[Licence Type] = 2)
GROUP BY YEAR(factuurregel.[Invoice date lease company]),factuurregel.[Internal costkind]
ORDER BY factuurregel.[Internal costkind]

Try this way in your WHERE Clause
WHERE datefieldsubquery = Convert(varchar(50),YEAR(GETDATE()))+'-12-31 23:59:00'

Related

Speed up my SQL Query? It is giving execution time out error

I have created this below query, which is calculating sum till each date. This query gives me exact result which am looking for, But the data which it has very big. How can I speed or optimize it?
IF OBJECT_ID('TEMPDB..#temp')IS NOT NULL
DROP TABLE #temp
IF OBJECT_ID('TEMPDB..#temp1')IS NOT NULL
DROP TABLE #temp1
Declare #DateFrom DateTime
Set #DateFrom = CONVERT(DATE,DATEADD(D,-datepart(d,getdate())+1,DATEADD(M,-1,GETDATE())))
Declare #DateTo DateTime
Set #DateTo = CONVERT(DATE,DATEADD(D,-DATEPART(D,getdate()),GETDATE()))
Select
Date
,[Item No_]
,case when Sum(ILE.Quantity)>0 and [Posting Date]=Date then Sum(ILE.Quantity) else 0 end AS [In Quantity],
case when Sum(ILE.Quantity)<0 and [Posting Date]=Date then Sum(ILE.Quantity) else 0 end AS [Out Quantity],
(Sum(ILE.Quantity))Closing
into #temp
from Calender C left Join [Snowman Logistics Limited$Item Ledger Entry]ILE on Cast(ILE.[Posting Date]as date)<=C.Date
Group by Date,[Item No_],[Posting Date]
Select Date,[Item No_]
,SUm([In Quantity])[In Quantity],Sum([Out Quantity])[Out Quantity],Sum(Closing)Closing from #temp where Date Between #DateFrom and #DateFrom
group by Date,[Item No_]
You can try:
in your first query you are interested in matches - you can try using INNER JOIN, if you still need [dates]-[items] even if there is no entry for them for the specified period in the [Snowman Logistics Limited$Item Ledger Entry] table, you can later;
why you need to cast [Posting Date] as date - if it is a string and not date/datetime type, you should change it in order to skip the explicit (or implicit) cast during the calculations
if 1 is OK and you can use INNER JOIN, you can try to create indexed view and have the initial query precalculated
In your first query you are grouping the records by [Posting Date] and in the second one, you are grouping the records again, excluding it - can't you unite the queries?
Select
Date
,[Item No_]
,case when Sum(ILE.Quantity)>0 and [Posting Date]=Date then Sum(ILE.Quantity) else 0 end AS [In Quantity],
case when Sum(ILE.Quantity)<0 and [Posting Date]=Date then Sum(ILE.Quantity) else 0 end AS [Out Quantity],
(Sum(ILE.Quantity))Closing
into #temp
from Calender C
left Join [Snowman Logistics Limited$Item Ledger Entry]ILE
on Cast(ILE.[Posting Date]as date) <= C.Date
where Date Between #DateFrom and #DateFrom
Group by Date,[Item No_]
Depending on how wide are your table and the types of the columns you can get performance boost if you create covering indexes - these type of indexes will include only the column you are using in your queries, so less data will be read(less IO).

How to select max date over the year function

I am trying to select the max date over the year, but it is not working. Any ideas on what to do?
SELECT a.tkinit [TK ID],
YEAR(a.tkeffdate) [Rate Year],
max(a.tkeffdate) [Max Date],
tkrt03 [Standard Rate]
FROM stageElite.dbo.timerate a
join stageElite.dbo.timekeep b ON b.tkinit = a.tkinit
WHERE a.tkinit = '02672'
and tkeffdate BETWEEN '2014-01-01' and '12-31-2014'
GROUP BY a.tkinit,
tkrt03,
a.tkeffdate
Perhaps you only want it by year and not rolled up by calendar date. For SQL server you can try this.
SELECT
…
MaxDate = MAX(a.tkeffdate) OVER (PARTITION BY a.tkinit, YEAR(a.tkeffdate)))
…
Or you could modify the query above to group by the year instead of date-->
GROUP BY a.tkinit,
tkrt03,
YEAR(a.tkeffdate)
You seem to want only one row and all the columns. Use ORDER BY and TOP:
SELECT TOP (1) tr.tkinit as [TK ID],
YEAR(tr.tkeffdate) as [Rate Year],
a.tkeffdate as [Max Date],
tkrt03 as [Standard Rate]
FROM stageElite.dbo.timerate tr JOIN
stageElite.dbo.timekeep tk
ON tk.tkinit = tr.tkinit
WHERE tr.tkinit = '02672' AND
tr.tkeffdate >= '2014-01-01' AND
tr.tkeffdate < '2015-01-01'
ORDER tr.tkeffdate DESC;
Note that I also fixed your date comparisons and table aliases.

SUM and Grouping by date and material

Still learning SQL forgive me.
I have 3 tables. a material table, a material_req table and a material_trans table. I want to group by material and then group columns by year.
so it would be [material, 2019, 2018, 2017, 2016, total (total being the total qty used for each material.
I have tried to place the date in the select statement, and grouped by the date also. but then the returned result is a lot of the same material with a lot of dates. I only need the year. maybe try the same and return just the year?
SELECT material_req.Material
-- , Material_Trans_Date
, SUM(-1 * material_trans.Quantity) AS 'TOTAL'
,Standard_Cost
FROM
Material_Req inner join Material_Trans
ON
Material_Req.Material_Req = Material_Trans.Material_Req
LEFt JOIN Material
ON
Material.Material = Material_Req.Material
WHERE
material_trans.Material_Trans_Date between '20180101' AND GETDATE()
-- Material_Trans_Date between '20180101' AND '20181231'
-- Material_Trans_Date between '20170101' AND '20171231'
-- Material_Trans_Date between '20160101' AND '20161231'
GROUP BY
material_req.Material ,Standard_Cost
ORDER BY
Material_Req.Material, Standard_Cost
expected results should by grouped by material, 2019, 2018, 2017,2016, Standard_Cost. the years column will have the sum of qty for each material for that year.
results look like this current_results
If you are using SQL Server then you might try this:
SELECT material_req.Material
, SUM(CASE WHEN DATEPART(YEAR, Material_Trans_Date) = '2019' THEN material_trans.Quantity ELSE 0 END) [2019 TOTAL]
, SUM(CASE WHEN DATEPART(YEAR, Material_Trans_Date) = '2018' THEN material_trans.Quantity ELSE 0 END) [2018 TOTAL]
,Standard_Cost
FROM
Material_Req inner join Material_Trans
ON
Material_Req.Material_Req = Material_Trans.Material_Req
LEFt JOIN Material
ON
Material.Material = Material_Req.Material
WHERE
material_trans.Material_Trans_Date between '20180101' AND GETDATE()
GROUP BY
material_req.Material ,Standard_Cost
ORDER BY
Material_Req.Material, Standard_Cost

Adding a number to a datetime to get new date SQL Server

I am trying to get the query below to assign a number value to the column 'DESIRED TRANSIT TIME' based on the value in that column - 10 if it starts with A and 5 if it starts with C. From there I want to add that number to REVISED_EX_FACTORY to get a new ex factory. I have never attempted this and using the query below I get the result which is the date plus the text 'DESIRED TRANSIT TIME' - which kind of makes sense since it is a string. How can I get the value in the column instead of the textual name of the column in line 20? I was told converting the datetime values to get rid of the time component was a good way to go.
The ideal result would be to either add 5 or 10 days to the date depending the value in 'DESIRED TRANSIT TIME'
SQL:
USE PDX_SAP_USER
GO
SELECT E.team_member_name [EMPLOYEE],
K.business_segment_desc [BUSINESS SEGMENT],
G.order_status [GPS ORDER STATUS],
H.po_type [PO TYPE],
G.order_no [GPS ORDER NO],
I.po_number [SAP PO NUMBER],
I.shipping_instruct [SAP SHIP MODE],
G.shipping_type [GPS SHIP MODE],
CASE
WHEN I.shipping_instruct LIKE 'A%'
THEN '10'
WHEN I.shipping_instruct LIKE 'C%'
THEN '5'
END [DESIRED TRANSIT TIME],
CONVERT(VARCHAR(12),I.revised_ex_factory,101) [LAST CONFIRMED DATE ],
CONVERT(VARCHAR(12),I.revised_ex_factory,101) + 'DESIRED TRANSIT TIME' AS 'PROPOSED ETA',
CONVERT(VARCHAR(12),S.po_estimated_deliv_date,101) [CURRENT DELIV DATE],
-- 'days_diff'
I.material [MATERIAL],
M.description [DESCRIPTION],
I.stock_category [STOCK CATEGORY],
I.po_ordered_quantity [PO ORDERED QUANTITY],
I.po_recvd_quantity [PO RECVD QUANTITY],
I.po_balance_quantity [PO BALANCE QUANTITY],
I.po_intransit_quantity [PO INTRANSIT QUANTITY],
I.plant_code [PLANT],
I.direct_ship_code [DS CODE],
I.comment [COMMENT]
FROM (SELECT order_no,
order_status,
shipping_type
FROM asagdwpdx_prod.dbo.SimoxOrder1
UNION ALL
SELECT order_no,
order_status,
shipping_type
FROM asagdwpdx_prod.dbo.SimoxOrder2
UNION ALL
SELECT order_no,
order_status,
shipping_type
FROM asagdwpdx_prod.dbo.SimoxOrder3) G
JOIN pdx_sap_user..vw_po_header H ON G.order_no = H.ahag_number
JOIN pdx_sap_user..vw_po_item I ON H.po_number = I.po_number
JOIN pdx_sap_user..vw_po_size S ON I.po_number = S.po_number
AND I.po_item_number = S.po_item_number
JOIN pdx_sap_user..vw_mm_material M ON I.material = M.material
JOIN pdx_sap_user..vw_kd_business_segment K ON M.business_segment_code = K.business_segment_code
JOIN adi_user_maintained..scm_po_employee_name E ON I.po_number = E.po_number
WHERE I.po_balance_quantity > 0
AND I.del_indicator NOT IN ('L','S')
AND H.PO_TYPE NOT IN ('01','UB')
AND I.shipping_instruct IN ('A1','A2','A5','C1','C2','C3')
SAMPLE RESULT:
04/30/2016DESIRED TRANSIT TIME
So you have two options. The first is to duplicate the CASE statement you have a second time, and concatenate that with the date. That's probably the most straight forward, although you will end up duplicating that code. It's a small duplication, but one none the less. If that bothers you, or you need to use it elsewhere in your query as well, you will need to wrap the whole thing in a subquery so you can reference the case statement as though it were a distinct column. e.g.
select
...
DesiredTransitTime =
case
when I.shipping_instruct LIKE 'A%'
then '10'
when I.shipping_instruct LIKE 'C%'
then '5'
end,
ProposedETA = convert(varchar(12),I.revised_ex_factory,101) +
case
when I.shipping_instruct LIKE 'A%'
then '10'
when I.shipping_instruct LIKE 'C%'
then '5'
end
...
or
select
[DESIRED TRANSIT TIME],
[PROPOSED ETA = StringDate + [DESIRED TRANSIT TIME]
...
from
(
select
StringDate = convert(varchar(12), I.revised_ex_factory,101) ,
[DESIRED TRANSIT TIME] =
case
when I.shipping_instruct LIKE 'A%'
then '10'
when I.shipping_instruct LIKE 'C%'
then '5'
end,
...
) a

Subquery returned more than 1 rows inside case statement

I have been working on a query whereby in a subquery I am selecting the column Cust_Status under certain conditions.
select distinct
C.Cust_Code [Cust #],
C.Cust_Start_Date [Start Date],
C.Cust_End_date [End Date],
(select
Cust_Status = (case
when cast(CUST_UPDATE_DATE_LT as DATE) = cast('2017-01-23 00:00:00' as Date)
then 'V'
when cast(CUST_UPDATE_DATE_LT as DATE) = cast('2017-01-22 00:00:00' as Date)
then 'I'
end)
from tblCustomers) [Cust Status],
M.Machine_ID,
M.Machine_Location
from
tblCustomers C
inner join
tblMachine M on C.Cust_Mach_Pkey = M.Pkey
When I run this query I get an error
subquery returned more than 1 value error.
When I remove the subquery inside case, it's fine. But I am sure there is only 1 record present for both date conditions. So not sure how my subquery returning more than 1 values. Please enlighten me.
I am guessing that you just want to compare the latest date. If so, there are much simpler ways:
select C.Cust_Code as [Cust #], C.Cust_Start_Date as [Start Date],
C.Cust_End_date as [End Date],
(case when max(cast(CUST_UPDATE_DATE_LT as DATE)) = '2017-01-23'
then 'V'
when max(cast(CUST_UPDATE_DATE_LT as DATE)) = '2017-01-22'
then 'I'
end) as Cust_status
M.Machine_ID,
M.Machine_Location
from tblCustomers C inner join
tblMachine M
on C.Cust_Mach_Pkey = M.Pkey
group by C.Cust_Code, C.Cust_Start_Date, C.Cust_End_date,
M.Machine_ID, M.Machine_Location