How to select a date interval in postgresql query? - postgresql

I have query like this:
select d.id from days as d JOIN tv_programs AS t ON (d.tv_program_id = t.id) WHERE d.date=? AND t.type=0 ORDER BY d.date, t.date DESC OFFSET 1;
it returns data for 1 selected date (type Date), but i want to get values from startDate to endDate, for example, i want to do it using one query which do something like that:
select d.id from days as d JOIN tv_programs AS t ON (d.tv_program_id = t.id) WHERE d.date='2011-09-01' AND t.type=0 ORDER BY d.date, t.date DESC OFFSET 1;
select d.id from days as d JOIN tv_programs AS t ON (d.tv_program_id = t.id) WHERE d.date='2011-09-02' AND t.type=0 ORDER BY d.date, t.date DESC OFFSET 1;
select d.id from days as d JOIN tv_programs AS t ON (d.tv_program_id = t.id) WHERE d.date='2011-09-03' AND t.type=0 ORDER BY d.date, t.date DESC OFFSET 1;
It's possible?

... where d.date between '2011-09-01' and '2011-09-04' should work.

Related

pySpark error Expression Referencing the outer Query

I want to recreate this query in spark sql
SELECT
[Id],
[Group],
[Name],
min([Date]) as MinDate,
max([Date]) as MaxDate
FROM recordTable
GROUP BY [Id],[Group],[Name]
)
SELECT
t.Id,
t.[Group],
t.[Name],
c.[Date],
(SELECT top 1 ScoreCount
from recordTable x
where x.[Date] <= c.[Days]
and x.[Group] = t.[Group]
and x.[Name] = t.[Name]
order by x.[Date] desc
) ScoreCount
FROM t
LEFT JOIN calendar c ON c.[Days] BETWEEN t.MinDate AND t.MaxDate
so I have
df = spark.sql("""
WITH t as (
SELECT
Id,
Group,
Name,
min(Date) as MinDate,
max(Date) as MaxDate
FROM recordTable
GROUP BY Id,Group,Name
)
SELECT
t.Id,
t.Group,
t.Name,
c.Date,
(SELECT ScoreCount
from recordTable x
where x.Date <= c.Days
and x.Group = t.Group
and x.Name = t.Name
order by x.Date desc LIMIT 1
) ScoreCount
FROM t
LEFT JOIN calendar c ON c.Days BETWEEN t.MinDate AND t.MaxDate
""")
But I'm getting an error when trying to limit 1 and using an order by clause. Any alternatives?
"Expressions referencing the outer query are not supported outside of where/having clauses"

Select the last record for the date and time columns

I need to select the last record in the academic table which has two columns for date and time. When I run the query I get an error. Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
USE PCUnitTest
SELECT C.ACCOUNTNO, C.CONTACT, C.LASTNAME, C.KEY4, A.PEOPLE_ID, A.APP_STATUS, A.APP_DECISION, A.REVISION_DATE, A.REVISION_TIME
FROM ACADEMIC AS A INNER JOIN
GM.dbo.CONTACT1 AS C ON A.PEOPLE_ID = C.KEY4
WHERE A.REVISION_DATE = (SELECT TOP (1) REVISION_DATE, REVISION_TIME, PEOPLE_CODE, PEOPLE_ID, PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, ACADEMIC_SESSION, PROGRAM, DEGREE, CURRICULUM
FROM PCUnitTest.dbo.ACADEMIC
ORDER BY REVISION_DATE DESC, REVISION_TIME DESC)
You can Join the query you are using in the where
USE PowerCampusUnitTest
SELECT C.ACCOUNTNO, C.CONTACT, C.LASTNAME, C.KEY4, A.PEOPLE_ID, A.APP_STATUS, A.APP_DECISION, A.REVISION_DATE, A.REVISION_TIME
FROM ACADEMIC AS A
INNER JOIN GoldMineUnitTest.dbo.CONTACT1 AS C
ON A.PEOPLE_ID = C.KEY4
INNER JOIN (
SELECT TOP 1 A2.REVISION_DATE,A2.REVISION_TIME FROM PowerCampusUnitTest.dbo.ACADEMIC A2
ORDER BY REVISION_DATE DESC, REVISION_TIME DESC
)AS A2
ON A.REVISION_DATE = A2.REVISION_DATE AND A.REVISION_TIME = A2.REVISION_TIME
Use ROW_NUMBER()
USE PCUnitTest
SELECT
R.ACCOUNTNO, R.CONTACT, R.LASTNAME, R.KEY4, R.PEOPLE_ID, R.APP_STATUS, R.APP_DECISION, R.REVISION_DATE, R.REVISION_TIME
FROM
(
SELECT C.ACCOUNTNO, C.CONTACT, C.LASTNAME, C.KEY4, A.PEOPLE_ID, A.APP_STATUS, A.APP_DECISION, A.REVISION_DATE, A.REVISION_TIME
,ROW_NUMBER() OVER (ORDER BY A.REVISION_DATE DESC, A.REVISION_TIME DESC) RN
FROM ACADEMIC AS A INNER JOIN
GMUnitTest.dbo.CONTACT1 AS C ON A.PEOPLE_ID = C.KEY4
) R
WHERE RN=1
If you want to get the latest row for each PEOPLE_ID, then add PARTITION BY
SELECT
R.ACCOUNTNO, R.CONTACT, R.LASTNAME, R.KEY4, R.PEOPLE_ID, R.APP_STATUS, R.APP_DECISION, R.REVISION_DATE, R.REVISION_TIME
FROM
(
SELECT C.ACCOUNTNO, C.CONTACT, C.LASTNAME, C.KEY4, A.PEOPLE_ID, A.APP_STATUS, A.APP_DECISION, A.REVISION_DATE, A.REVISION_TIME
,ROW_NUMBER() OVER (PARTITION BY A.PEOPLE_ID ORDER BY A.REVISION_DATE DESC, A.REVISION_TIME DESC) RN
FROM ACADEMIC AS A INNER JOIN
GMUnitTest.dbo.CONTACT1 AS C ON A.PEOPLE_ID = C.KEY4
) R
WHERE RN=1

Join two queries become one subquery

I want to ask how to combine these two queries become one subquery?
select c.CustomerName, A.Qty
from Customer c join (select s.CustomerID, pd.Date, s.Qty
from Period pd join Sales s on pd.TimeID = s.TimeID) A on c.CustomerID = A.CustomerID
where #Date = A.Date
and
select sum(case when (pd.Date between '2010-03-15' and #Date) then s.Qty else 0 end) as TotalQty
from Period pd full join Sales s on pd.TimeID = s.TimeID full join Customer c on s.CustomerID = c.CustomerID
group by c.CustomerName, c.CustomerID
They should result one table contains these following columns: CustomerName, Qty, and TotalQty. I've tried many ways but they didn't work at all. Really hope your help, thanks.
Answering your question assuming you are looking at the result as one row and not "column" :
select c.CustomerName, A.Qty,(select sum(case when (pd.Date between '2010-03-15' and #Date) then s.Qty else 0 end)
from Period pd full join Sales s on pd.TimeID = s.TimeID full join Customer c on s.CustomerID = c.CustomerID
group by c.CustomerName, c.CustomerID
) as TotalQty
from Customer c join (select s.CustomerID, pd.Date, s.Qty
from Period pd join Sales s on pd.TimeID = s.TimeID) A on c.CustomerID = A.CustomerID
where #Date = A.Date
If you still want the result as a single column , google "row to column transpose"

How to display rollup data in new column?

I have the following query which returns the number of android questions per each day on StackOverflow in the year of 2011. I want to get the sum of all the questions asked during the year 2011. For this I am using ROLLUP.
select
year(p.CreationDate) as [Year],
month(p.CreationDate) as [Month],
day(p.CreationDate) as [Day],
count(*) as [QuestionsAskedToday]
from Posts p
inner join PostTags pt on p.id = pt.postid
inner join Tags t on t.id = pt.tagid
where
t.tagname = 'android' and
p.CreationDate > '2011-01-01 00:00:00'
group by year(p.CreationDate), month(p.CreationDate),day(p.CreationDate)
​with rollup
order by year(p.CreationDate), month(p.CreationDate) desc,day(p.CreationDate) desc​
This is the output:
The sum of all questions asked on each day in 2011 is being displayed in the QuestionsAskedToday column itself.
Is there a way to display the rollup in a new column with an alias?
Link to the query
To show this as a column rather than a row you can use SUM(COUNT(*)) OVER () instead of ROLLUP. (Online Demo)
SELECT YEAR(p.CreationDate) AS [Year],
MONTH(p.CreationDate) AS [Month],
DAY(p.CreationDate) AS [Day],
COUNT(*) AS [QuestionsAskedToday],
SUM(COUNT(*)) OVER () AS [Total]
FROM Posts p
INNER JOIN PostTags pt
ON p.id = pt.postid
INNER JOIN Tags t
ON t.id = pt.tagid
WHERE t.tagname = 'android'
AND p.CreationDate > '2011-01-01 00:00:00'
GROUP BY YEAR(p.CreationDate),
MONTH(p.CreationDate),
DAY(p.CreationDate)
ORDER BY YEAR(p.CreationDate),
MONTH(p.CreationDate) DESC,
DAY(p.CreationDate) DESC
You could take an approach like this: Example
SELECT
YEAR(p.CreationDate) AS 'Year'
, CASE
WHEN GROUPING(MONTH(p.CreationDate)) = 0
THEN CAST(MONTH(p.CreationDate) AS VARCHAR(2))
ELSE 'Totals:'
END AS 'Month'
, CASE
WHEN GROUPING(DAY(p.CreationDate)) = 0
THEN CAST(DAY(p.CreationDate) AS VARCHAR(2))
ELSE 'Totals:'
END AS [DAY]
, CASE
WHEN GROUPING(MONTH(p.CreationDate)) = 0
AND GROUPING(DAY(p.CreationDate)) = 0
THEN COUNT(1)
END AS 'QuestionsAskedToday'
, CASE
WHEN GROUPING(MONTH(p.CreationDate)) = 1
OR GROUPING(DAY(p.CreationDate)) = 1
THEN COUNT(1)
END AS 'Totals'
FROM Posts AS p
INNER JOIN PostTags AS pt ON p.id = pt.postid
INNER JOIN Tags AS t ON t.id = pt.tagid
WHERE t.tagname = 'android'
AND p.CreationDate >= '2011-01-01'
GROUP BY ROLLUP(YEAR(p.CreationDate)
, MONTH(p.CreationDate)
, DAY(p.CreationDate))
ORDER BY YEAR(p.CreationDate)
, MONTH(p.CreationDate) DESC
, DAY(p.CreationDate) DESC​​​​​​​
If this is what you wanted, the same technique can be applied to Years as well to total them in the new column, or their own column, if you want to query for multiple years and aggregate them.

SQL Join Statement Issue

I'm tring to grab all fields from the latest Cash record, and then all fields from the related TransactionInfo record. I can't quite get this to work yet:
select t.*, top 1 c.* from Cash c
inner join TransactionInfo t
on c.TransactionID = t.id
order by c.createdOn desc
select top 1 *
from Cash c
inner join TransactionInfo t on c.TransactionID = t.id
order by createdOn desc
What's that top 1 doing there? If you only want one row then the TOP(1) must come first:
SELECT TOP(1) t.*, c.*
FROM Cash c
INNER JOIN TransactionInfo t
ON c.TransactionID = t.id
ORDER BY c.createdOn DESC
select t.,c.
from (Select top 1 * from Cash order by createdOn desc
) c
inner join TransactionInfo t
on c.TransactionID = t.id
order by createdOn desc
DOn;t use select * especially with a join, it wastes server resources.
SELECT c.*, t.* FROM cash c, transactioninfo t
WHERE c.infoid = t.id AND c.createdOn = (SELECT max(createdOn) FROM cash WHERE infoId = t.id) ORDER BY transactiontabledate desc
You need to find the record with the latest date from the cash table for each transactionId and use that also to filter it out in your query.