SQL convert string into datetime in where clause issue - sql

I'm trying to retrieve data from a wordpress database.
I can't find the syntax error in my query, can somebody help me with this?
It's to list the first 10 posts from specific post_type and with its Events_Date field converted into datetime.
Here is my query:
SELECT wp_posts.*, wp_postmeta.*
FROM ritmica_wp.wp_posts, ritmica_wp.wp_postmeta
WHERE convert(datetime, wp_postmeta.meta_value, 120) > GetDate()
IN
(SELECT wp_posts.*, wp_postmeta.* FROM ritmica_wp.wp_posts, ritmica_wp.wp_postmeta
WHERE wp_posts.post_type = 'event'
AND wp_postmeta.meta_key = 'Events_Date' )
ORDER BY wp_postmeta.meta_value ASC LIMIT 10

I don't see the point of the sub-query. Can't you just do:
SELECT TOP 10
wp_posts.*, wp_postmeta.*
FROM
ritmica_wp.wp_posts, ritmica_wp.wp_postmeta
WHERE
convert(datetime, wp_postmeta.meta_value, 120) > GetDate()
AND wp_posts.post_type = 'event'
AND wp_postmeta.meta_key = 'Events_Date'
ORDER BY
wp_postmeta.meta_value ASC
(for SQL Server)

Related

Is it possible to speed up this join?

The values table has millions of rows and doing this join on the indexes is quite slow (7s).
Is it possible to speed this up?
select *
from (
select
instance.Name, Date, Value,
instance.Category, instance.CreatedDate
from ValuesTable ValuesTable
join (
select
max(IDX) ID,
CreatedDate,
max(ModelsTable.Category) Category,
max(InstanceTable.Name) Name,
max(ModelsTable.Region) Country
from InstanceTable
join ModelsTable ModelsTable
on ModelsTable.ModelID = InstanceTable.ModelID
where InstanceTable.RunCategory = 'Scenario'
and CreatedDate = GETDATE()
group by InstanceTable.Name, ModelsTable.Category,
InstanceTable.CreatedDate
) instance on instance.ID=ValuesTable.IDX
) a
First, I would simplify the query a bit by getting rid of the first subquery. And clarify it using table aliases:
select i.Name, i.Date, i.Value, i.Category, i.CreatedDate,
instance.id, instance.CreatedDate, instance.Category,
instance.Name, instancy.Country
from ValuesTable i join
(select max(IDX) as ID, CreatedDate,
max(m.Category) as Category,
max(i.Name) as Name,
max(m.Region) as Country
from InstanceTable i join
ModelsTable m
on m.ModelID = i.ModelID
where i.RunCategory = 'Scenario' and
i.CreatedDate = GETDATE()
group by i.Name, m.Category, i.CreatedDate
) instance
on i.ID = instance.IDX;
Then, this is highly unlikely to do anything useful. The problem is:
i.CreatedDate = GETDATE()
GETDATE() is a non-standard function. But in every database that I know of that supports it, the function returns a time as well as a date. You probably intend:
i.CreatedDate = cast(GETDATE() as date)
or:
i.CreatedDate >= cast(GETDATE() as date)
You probably want to convert it to a date for the aggregation as well.
Then, you want indexes on:
InstanceTable(RunCategory, CreatedDate)
ModelsTable(ModelId)
ValuesTable(id)

How to combine 2 SQL statements into one table

I have 2 SQL statements to look up successful transactions and failed transactions.
SELECT COUNT (code_reseller) as trx_success, kode_reseller
FROM transaksi
where status = '20' AND CAST (date_entri AS DATE) = CAST (GETDATE() AS DATE)
group by code_reseller
ORDER BY trx_success DESC
AND
SELECT COUNT (code_reseller) as trx_fail, kode_reseller
FROM transaksi
where status > '20' AND CAST (date_entri AS DATE) = CAST (GETDATE() AS DATE)
group by code_reseller
ORDER BY trx_fail DESC
How to combine into one table with 3 columns result with code_reseller, trx_success and trx_fail?
Use conditional aggregation and combine the queries:
SELECT
kode_reseller,
COUNT(CASE WHEN status = '20' THEN 1 END) AS trx_success,
COUNT(CASE WHEN status > '20' THEN 1 END) AS trx_fail
FROM transaksi
WHERE
CAST(date_entri AS DATE) = CAST(GETDATE() AS DATE)
GROUP BY
kode_reseller;
The strategy here is to move the filtering on the status column which previously appeared in the two WHERE clauses into the conditional counts in the SELECT clause. The restriction on date_entri can stay there, since both queries have it.
As suggested by #Dale k, you can do it like this.
You cannot add order by inside, so create an alias table and give order by condition.
SELECT *
FROM
(
SELECT COUNT (code_reseller) as trx_success, kode_reseller
FROM transaksi
WHERE status = '20' AND CAST (date_entri AS DATE) = CAST (GETDATE() AS DATE)
GROUP BY code_reseller
UNION ALL
SELECT COUNT (code_reseller) as trx_fail, kode_reseller
FROM transaksi
WHERE status > '20' AND CAST (date_entri AS DATE) = CAST (GETDATE() AS DATE)
GROUP BY code_reseller
) a
ORDER BY a.trx_success DESC --here we get first select query table' column name and datatype and no of column will be same required in union/union all

Adding months in where clause in sql

I am writing a sp for getting the data for the next 6 months for a particular date field,
SELECT CR.[Id] AS ClaimId
,CR.[BOLNumber]
,CR.[PRONumber]
,CR.[ClaimNumber]
,CR.[CompanyName]
,c.NAME AS CarrierName
,CR.[DateFiled]
,CONVERT(VARCHAR(10),CR.[DateFiled], 103) AS DateFiledString
,CR.[ClaimDate] AS ClaimReceivedDate
,CONVERT(VARCHAR(10), CR.[ClaimDate], 103) AS ClaimReceivedDateString
,CR.[AmountFiled]
,CR.[Status] AS StatusId
,CR.[SettledAmount]
FROM CarrierRate.Claims AS CR WITH (NOLOCK)
WHERE CR.CustomerId = #AccountUserId AND
CR.Status = #statusType AND CR.ClaimDate < DATEADD(month,6,CR.ClaimDate)
ORDER BY CR.[Status] ASC
The field is ClaimDate. So am i doing it right or anything to be changed?
Please suggest
You can try
CONVERT(DATE, CR.ClaimDate) < DATEADD(MONTH,6,CONVERT(DATE, CR.ClaimDate))
only date is considered here.
Use BETWEEN keyword to specify date range.
WHERE CR.CustomerId = #AccountUserId AND
CR.Status = #statusType AND
CR.ClaimDate BETWEEN GETDATE() AND DATEADD(month,6,CR.ClaimDate)
(CR.ClaimDate BETWEEN DATEADD(month,-6,GETDATE()) AND GETDATE()
OR #statusType <> 2)

SQL Server: How to limit stored procedure to only show one (next) matching record

I am using the following stored procedure to fetch some data from a database.
The column meetingDate is formatted as datetime and only contains valid data.
How do I have to amend the stored procedure so that it only shows me the next matching record and not all of them ?
Example:
Today = 18/02/2014;
the database contains records with meetingDate = 20/02/2014, 27/02/2014 and 04/03/2014;
in that case the result should only be the record for 20/02/2014 as the next matching one in the future.
My stored procedure:
ALTER PROCEDURE [dbo].[FetchMeetings]
AS
BEGIN
SET NOCOUNT ON;
SELECT A.meetingID,
CONVERT(VARCHAR(11), A.meetingDate, 106) AS meetingDate,
A.created,
A.createdBy,
A.updated,
A.updatedBy,
B.speaker AS speaker,
B.topic AS topic
FROM MeetingDates A
INNER JOIN MeetingDetails B
ON A.meetingID = B.meetingID
WHERE meetingDate >= GETDATE()
ORDER BY meetingDate, speaker, topic
FOR XML PATH('meeting'), ELEMENTS, TYPE, ROOT('ranks')
END
Many thanks for any help with this, Tim.
Use SELECT TOP 1
SELECT A.meetingID,
CONVERT(VARCHAR(11), A.meetingDate, 106) AS meetingDate,
A.createdBy,
B.speaker AS speaker,
B.topic AS topic
FROM MeetingDates A
INNER JOIN MeetingDetails B
ON A.meetingID = B.meetingID
WHERE a.meetingDate IN (
SELECT TOP 1(a.meetingDate)
FROM MeetingDates A
WHERE meetingDate >= GETDATE()
ORDER BY meetingDate ASC)
ORDER BY speaker, topic
FOR XML PATH('meeting'), ELEMENTS, TYPE, ROOT('ranks')
Use windowed function. it's compatible sql server 2005+
here is an example with my data
with p as (
select *, dense_RANK() over (order by foryear desc, formonth desc) as rnk
from RISK_TRANS.dbo.mytable
)
select * from p
where rnk = 2
My keys are 2014 - 1 for last and 2013-12; 2013-11. It only picks me 2013-12 as you would expect
can you try this : (i'm not sure syntax is correct, i only did the changes, not runned)
ALTER PROCEDURE [dbo].[FetchMeetings]
AS
BEGIN
SET NOCOUNT ON;
with p as (
SELECT A.meetingID,
CONVERT(VARCHAR(11), A.meetingDate, 106) AS meetingDate,
A.created,
A.createdBy,
A.updated,
A.updatedBy,
B.speaker AS speaker,
B.topic AS topic,
DENSE_RANK() over (order by CONVERT(VARCHAR(11), A.meetingDate, 106) desc) rnk
FROM MeetingDates A
INNER JOIN MeetingDetails B
ON A.meetingID = B.meetingID
WHERE meetingDate >= GETDATE())
select meetingid, meetingdate, createddate, createdby, updated, updatedby, speaker, topic
from p
ORDER BY meetingDate, speaker, topic
FOR XML PATH('meeting'), ELEMENTS, TYPE, ROOT('ranks')
END
try using SELECT 1 construction, check here 1

No column name was specified for column 2 of 't' T_SQL error

PLease i want to return only debtorid from this T-SQL . It gives the error "
No column name was specified for column 2 of 't'." My query is below.
with t as
(SELECT debtorid,MAX(dbo.FollowUp.followupdate) FROM dbo.FollowUp WITH (NOLOCK) WHERE
( dbo.FollowUp.FollowUpDate >= '01-01-2011 00:00:00:000' and dbo.FollowUp.FollowUpDate <= '01-13-2014 23:59:59.000'
and Status = 'PTP') GROUP BY [Status], DebtorId)
SELECT t.debtorid FROM t;
WIth my little knowledge , i thought the above should work fine for me. however, it didn't.Any help would be appreciated.
You need to add a name to your second column, e.g.:
with t as
(SELECT debtorid, MAX(dbo.FollowUp.followupdate) maxFollowup
FROM dbo.FollowUp WITH (NOLOCK)
WHERE dbo.FollowUp.FollowUpDate >= '01-01-2011 00:00:00:000'
and dbo.FollowUp.FollowUpDate <= '01-13-2014 23:59:59.000'
and Status = 'PTP'
GROUP BY [Status], DebtorId)
SELECT t.debtorid FROM t;
You are using Common Table Expressions or CTE, in CTE you must have column name as per msdn. You can also refer for CTE best practices:
http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
http://blog.sqlauthority.com/2011/05/10/sql-server-common-table-expression-cte-and-few-observation/
;with t as
(
SELECT FWP.debtorid
,MAX(FWP.followupdate) followupdate
FROM dbo.FollowUp FWP WITH (NOLOCK)
WHERE
(
FWP.FollowUpDate >= '01-01-2011 00:00:00:000'
and FWP.FollowUpDate <= '01-13-2014 23:59:59.000'
and FWP.Status = 'PTP'
) GROUP BY FWP.[Status], FWP.DebtorId
)
SELECT t.debtorid FROM t;