need query without cross join - netezza

i have a table which has sales at day level
sales_day
loc_id day_id sales
124 2013-01-01 100
124 2013-01-02 120
124 2013-01-03 140
124 2013-01-04 160
124 2013-01-05 180
124 2013-01-06 200
124 2013-01-07 220
there is weekly table which is the aggregate of all the days
loc_id week_id sales
123 201401 1120
Now i need all of the above in table as below
loc_id day_id sales week_sales
124 2013-01-01 100 1120
124 2013-01-02 120 1120
124 2013-01-03 140 1120
124 2013-01-04 160 1120
124 2013-01-05 180 1120
124 2013-01-06 200 1120
124 2013-01-07 220 1120
there are so many loactions and so many weeks,days.
How to get the data exactly without cross join.

Have you tried this:
select loc_id, day_id, sales, week_sales
from table
cross join (
select sum(sales) as week_sales from table
) t

Window analytical function should help you here...
select loc_id,
day_id,
sales,
sum(sales) over(partition by loc_id,date_part('week', day_id)) as week_total_sales
from <table name>
It will sum the sales by location id and the week of the year to give you the total you are looking for.
In your example, 2013-01-07 was included with the other dates, but it isn't actually part of the same calendar week.
It wasn't clear which DBMS you were referring to. The above is for Netezza. For SQL Server etc try changing date_part('week',day_id) to datepart(ww,day_id).

Related

Determine 'active' records

I have a list of customers that can have a single, or multiple, service listed. In the table that houses the changes over time there is an indicator of 'Added' or 'Removed'.
What I need: determine those service(s) that are currently active, if at all.
Here is a sample set of data:
CUST_ID SRV_ID STATUS ACTION_DATE
12345 102 Added 1/31/17 10:15
12345 189 Added 4/18/17 15:37
12345 189 Removed 4/21/17 14:08
12345 194 Added 5/2/17 14:43
12345 194 Removed 5/5/17 10:02
12345 194 Added 5/5/17 13:06
12345 69 Added 4/19/17 9:36
12345 69 Removed 5/2/17 14:43
12345 73 Added 4/20/17 10:21
12345 73 Removed 4/25/17 11:20
12345 95 Added 5/4/17 9:48
12345 95 Removed 5/4/17 10:05
Records to be returned: 102 on 1/31/17 10:15 and 194 on 5/5/17 13:06
You can find the latest row for each cust_id and serv_id using top 1 with ties and window function row_number and then filter those with status "Added":
select *
from (
select top 1
with ties *
from your_table
order by row_number() over (
partition by cust_id, srv_id
order by action_date desc
)
) t
where status = 'Added'
Produces:
CUST_ID SRV_ID STATUS ACTION_DATE
12345 102 Added 2017/01/31 10:15
12345 194 Added 2017/05/05 13:06
Demo
Like this:
SELECT SRV_ID
FROM YourTable
GROUP BY SRV_ID
HAVING MAX(CASE WHEN STATUS='Added' THEN ACTION_DATE END)
> MAX(CASE WHEN STATUS='Removed' THEN ACTION_DATE END)

How to bulk update the date column

I have a table with 10000 records.
Sample
Id Transaction_Id Contract_Id Contractor_Id ServiceDetail_Id ServiceMonth UnitsDelivered CreateDate
----------------------------------------------------------------------------------------------------------------------------
1 1 352 466 590 2016-03-01 203 2016-04-25 17:01:55.000
2 1 352 466 566 2016-03-01 200 2016-04-25 17:02:38.807
3 1 352 466 138 2016-04-13 20 2016-04-13 00:00:00.000
5 1 352 466 138 2016-04-14 21 2016-04-13 00:00:00.000
6 10011 40 460 68 2016-03-17 10 2016-04-25 17:20:13.413
7 10011 40 460 511 2016-03-17 15 2016-04-25 17:20:13.413
8 10011 40 460 1611 2016-03-17 20 2016-04-25 17:20:13.413
9 20011 352 466 2563 2016-02-05 10 2016-04-25 17:20:25.307
11 100 40 460 68 2016-03-17 10 2016-04-25 17:29:23.653
In this table I have servicemonth with different dates.
I want to update the servicemonth column to the existing months last date.
suppose if I have 2016-03-17 in the table, it should be updated to 2016-3-31
suppose if I have 2016-05-12 in the table, it should be updated to 2016-5-31
Can anyone suggest a single query to update this?
EOMONTH: Returns the last day of the month that contains the specified date, with an optional offset.
UPDATE ... SET servicemonth = EOMONTH(servicemonth)
Update servicemonth
set servicemonth = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
--replace getdate() with the date column for which you want the end day of the month

Most recent entry of a record in an Access report

I am trying to retrieve the most recent entry of a record in an Access report. The query I have gives me the results in SQL-Server but row_number is not compatible with Access. Its been suggested that I use the max function in Access. Can you assist me in generating this report?
SELECT cID, CName, Address, Project#, JobOwner, SubStatusID, Status, JNJobID, JNNote
FROM (
SELECT
cID, CName, Address, Project#, JobOwner, SubStatusID, Status, JNJobID, JNNote
, ROW_NUMBER() OVER (PARTITION BY JNJobID ORDER BY JNDate DESC) AS r
FROM [JobNotes]
Left JOIN Jobs ON [JobNotes].JNJobID = Jobs.JobID
Left JOIN Addresses ON Jobs.JobAddressID = Addresses.AddressID
Left JOIN Customers ON Jobs.JobCustomerID = Customers.CID
Left JOIN Status ON Jobs.JobSubStatusID = Status.StatusID
) x
WHERE r = 1 and customerID = 134 and jobsubstatusid <> 14 and jobsubstatusid <> 15 and jobsubstatusid <> 16 and jobsubstatusid <> 42 and jobsubstatusid <>38 and jobsubstatusid <>75
Jobs Table
JobID Project# JobOwner JobStatusID AddressID JobCustomerID
6972 PN1 John 1 333 222
6973 PN2 Sarah 3 444 666
6974 PN3 James 6 555 777
Address Table
AddressID Address
333 1333 Janes Ln
444 5555 Davis Blvd
555 888 Post Rd
Customer Table
CID CName
222 Builder
666 HomeOwner
777 HOA
JobNotes Table
JobNotesID JNJobID JNDate JNNote
11800 6972 2016-03-15 00:00:00.000 Example 1
11874 6972 2016-03-17 00:00:00.000 Example 2
12181 6972 2016-03-25 00:00:00.000 Example 3
12006 6973 2016-03-21 00:00:00.000 Example 4
11961 6974 2016-03-18 00:00:00.000 Example 5
11924 6974 2016-03-17 00:00:00.000 Example 6
JobNotes Table
CID CName Address Project# JobOwner SubStatusID Status JNJobID JNNote
222 Builder 1333 Janes Ln PN1 John 1 Sales 6972 Example 3
666 HomeOwner 5555 Davis Blvd PN2 Sarah 3 Design 6973 Example 4
777 HOA 888 Post Rd PN3 James 6 Construction 6974 Example 6

How to get the latest value per time interval in SQL Server

SELECT RIGHT(timestamp,LEN(timestamp) -12) as DailyTime, left(roundtrip, LEN(roundtrip) -2) as HalfHourDuration, site_code
FROM tblServer_Status
WHERE timestamp >= dateadd(day, datediff(day,'19000101',CURRENT_TIMESTAMP),'19000101') AND timestamp < dateadd(day, datediff(day,'19000101',CURRENT_TIMESTAMP)+1,'19000101') AND server = 'ServerName' AND site_code = 'A'
GROUP BY timestamp, roundtrip, site_code HAVING(((COUNT(site_code))>0))
ORDER BY timestamp
I have this code that gives me this kind of output
| DailyTime | HalfHourDuration | Site_Code|
12:00AM 122 A
12:00AM 143 A
12:00AM 242 A
12:30AM 112 A
12:30AM 222 A
12:30AM 462 A
01:00AM 322 A
01:00AM 642 A
01:00AM 322 A
01:30AM 146 A
01:30AM 167 A
01:30AM 116 A
02:00AM 163 A
02:00AM 145 A
02:00AM 121 A
02:30AM 149 A
02:30AM 135 A
02:30AM 111 A
...................................
But I need to get the Latest duration per time.
Like this one
| DailyTime | HalfHourDuration | Site_Code|
12:00AM 242 A
12:30AM 462 A
01:00AM 322 A
01:30AM 116 A
02:00AM 121 A
02:30AM 111 A
Something like that.
can anyone help me configure my codes.
Thanks.
You can do this using row_number():
with t as (
<your query here without order by>
)
select t.*
from (select t.*,
row_number() over (partition by DailyTime
order by HalfHourDuration desc
) as seqnum
from t
) t
where seqnum = 1;
Add Max function to your column HalfHourDuration.
This will list out the maximum value of the roundtrip alone grouping by timestamp

Handle condition in select statement

I have a table like this:
customer:
customerID joineddate
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
211 2004-12-10 00:00:00.000
231 2004-12-10 00:00:00.000
231 2004-11-10 00:00:00.000
411 2008-12-10 00:00:00.000
531 2009-12-10 00:00:00.000
I have written the query from 2 tables where I do a join and get the result like the above. But I need to get the result like this where I need to input my condition and get the result like below.
customerID joineddate indicator
111 2004-12-10 00:00:00.000 3
211 2004-12-10 00:00:00.000 1
231 2004-12-10 00:00:00.000 1
231 2004-11-10 00:00:00.000 1
411 2008-12-10 00:00:00.000 1
531 2009-12-10 00:00:00.000 1
Having absolutely no clue what your other table is named or how it is related to the customer table, here is my best guess:
SELECT c.customerID, o.joineddate, indicator = COUNT(*)
FROM dbo.customer AS c
INNER JOIN dbo.[other table] AS o
ON c.CustomerID = o.CustomerID
GROUP BY c.customerID, o.joineddate;
Google for keyword
GROUP BY
and the
COUNT()
function.

Resources