I have a table [Case] which amongst other fields has two ints, one called [CaseNo] and the other [QueryNo]. Only one of these will exist at any one time, the other will return Null.
I want a SELECT statement that will return [CaseNo] if it exists, and if it doesn't it should return the [QueryNo] proceeded by a 'Q' to denote it is a [QueryNo].
I tried the following statement -
SELECT CONVERT(VarChar(50), (ISNULL(CaseNo, 'Q' + QueryNo)))
FROM [Case]
But it does not like my Conversion.
Could someone please help me get the right Statement to achieve my objective.
Using a CASE statement:
Select Case when caseNo is null then 'Q'+ Convert(varchar(10),queryNo)
else Convert(varchar(10),caseNo) end as yourNo
from [Case]
Or if you like using isnull/coalesce, you could do:
Select isnull(Convert(varchar(10), caseNo),'Q' + Convert(varchar(10), queryNo)) yourNo
from [Case]
Related
I wanted to put 'No record' on the column instead of NULL if the datediff function returns a null value.
SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
CAST(
CASE
WHEN (datediff(HOUR,c.timein,c.timeout) IS NULL)
THEN 'No record'
END
), FROM tblCheckInOutDetail c RIGHT JOIN tblEmployee e on e.IdEmployee = c.IdEmployee WHERE e.IdEmployee = 55
So far this code only throws Incorrect syntax near 'CAST', expected 'AS'. but I don't know what data type should I put in the CAST parameter , since if there's a record it will show the datetime .
You need to convert the number value to a string. For this, you can use coalesce():
SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
COALESCE(CAST(datediff(HOUR, c.timein, c.timeout) AS VARCHAR(255)), 'No record')
FROM tblEmployee e LEFT JOIN
tblCheckInOutDetail c
ON e.IdEmployee = c.IdEmployee
WHERE e.IdEmployee = 55;
Note: I switched the RIGHT JOIN to a LEFT JOIN. They are equivalent logically. But most people find it much easier to follow the logic of the LEFT JOIN, because the table that defines the rows is the first table being read in the FROM clause.
Strictly answering question (though I don't understand why you need a CASE expression if you have working versions of the query), you can easily translate this to a CASE expression:
ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')
ISNULL really is just nice, convenient shorthand for CASE WHEN a IS NOT NULL THEN a ELSE b END, so:
CASE WHEN DATEDIFF(HOUR, c.timein, c.timeout) IS NOT NULL
THEN CAST(datediff(HOUR,c.timein,c.timeout) as varchar(11))
ELSE 'No Record' END
As you can see, a downside is that if you really really really want a CASE expression, you have to repeat at least the DATEDIFF to cover both the case where the outer row doesn't exist and the case where the outer row exists but one of the values is NULL.
Also note that you should always specify a length for variable types like varchar, even in cases where you think you're safe with the default.
I don't know if this is the correct option or usage.
but this works for me :
ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')
But can you guys show me how to do this using case expression?
I have problem setting a prefix in a case statement.
Data set:
missionid:
5505
5506
select
CASE
WHEN m.EXTLOCATIONID is not null THEN '01' + convert(nvarchar(50),m.missionid)
ELSE tg.ID_ACTIVITY
END as Barcode2
from MISSION m
left join TASKGROUP tg with(nolock) on m.MMPICKLISTID = tg.ID
When I run this query my result is this:
Barcode2:
15505
15506
Desired result is this:
015505
015506
As one can see, the first zero is not shown in the result. How can I achieve this?
CASE expression would always return one type so, you need to do conversion:
CASE WHEN m.EXTLOCATIONID is not null
THEN '01' + convert(nvarchar(50), m.missionid)
ELSE CONVERT(VARCHAR(255), tg.ID_ACTIVITY)
END as Barcode2
A case expression returns a single type. And, if different paths return different types -- say a string and a number -- then the result is a number. Those are the rules of SQL.
You are also mixing national character sets with "regular" characters. That seems unnecessary. I would recommend:
(CASE WHEN m.EXTLOCATIONID is not null
THEN CONCAT('01', m.missionid)
ELSE CONVERT(VARCHAR(255), tg.ID_ACTIVITY)
END) as Barcode2
I want to select multiple columns from single table based on my given input string in sql select statement.
Example :
If input="table_medical" i want to select the columns like medi_col1,medi_col2,medi_col2
If input="table_pharmacy" i want to select the columns like medi_phar1,medi_phar2,medi_phar1
sql("select
case when $input="table_medical" then medi_col1) //like this
please help me to complete this.
If you want this in a single query, then the same number of columns is needed -- and have compatible types.
One method uses union all:
select medi_col1, medi_col2, medi_col2
from t
where #input = 'table_medical'
union all
select medi_phar1, medi_phar2, medi_phar1
from t
where #input = 'table_pharmacy';
SET #input="table_medical";
SELECT
CASE WHEN #input="table_medical" THEN medi_col1 ELSE medi_phar1 END as medi_col1,
CASE WHEN #input="table_medical" THEN medi_col2 ELSE medi_phar2 END as medi_col2
CASE WHEN #input="table_medical" THEN medi_col3 ELSE medi_phar3 END as col3
FROM MyTable
Data types for medi_col1 and medi_phar1 needs to be same (and for the rest of columns too)
I have the following query:
DECLARE #BeginDateQ1 date = '01-01-2010', #EndDateQ1 date = '12-31-2010'
BEGIN
SELECT
H.Type, H.SN, Sum(H.Hours), H.Date as 'Report Date',
H.OName, R.ReceivedDate, R.Confirmed, R.Part AS 'Part Number'
FROM
Hours H
INNER JOIN
Repair R ON H.SN = R.SN
WHERE
(R.Confirmed NOT LIKE 'O%' AND R.Confirmed NOT LIKE 'Y%')
AND (H.Date BETWEEN #BeginDateQ1 AND #EndDateQ1)
GROUP BY
H.Type, H.SN, H.Date, H.OName, R.ReceivedDate, R.Confirmed, R.Part
ORDER BY
Date ASC
END
Which gives me my desired result.
I am having trouble with the following IF statement:
IF
(SELECT R.ReceivedDate FROM Repair BETWEEN #BeginDate1 AND #EndDate1)
THEN
COUNT(R.Confirmed)
END IF
ALSO, how would I properly include this IF statement in the original query that produced the original results I want?
NOTE that I need the count result from the IF statement to be used as a denominator for an equation and the numerator is the SUM(Hours) from line 3 of original query in the post.
This is a first time for me writing IF statements in SQL (only have done in C#). Any help would be appreciated. Thanks.
IF is a control flow statement, not to be used within a query.
IF (somecondition) THEN
<sql statements>
ELSE
<sql statements>
END
You can do that within a stored procedure. To do conditionals within a query, you need to use CASE...
SELECT col1, col2,
CASE when col1='x' then 'HIT' else 'MISS' END
from myTable
which would give you a result with three columns, in the last column you would have the text 'HIT' or 'MISS' based on the value in col1.
A case construct might be what you are after. Something like this.
, case when R.ReceivedDate BETWEEN #BeginDate1 AND #EndDate1
then count(r.confirmed) else sum(0) end confirmations
Edit Starts Here
Note that this answer only shows the general idea. Since the OP mentioned later that the result is to be a denominator, the alias has to go away. Also, sum(0) has to be replaced by something representing sum(hours), whatever that might be
If you want to see if the query returns any rows, use EXISTS()
IF EXISTS(SELECT R.ReceivedDate FROM Repair BETWEEN #BeginDate AND #EndDate)
BEGIN
...
END
Is there an equivalent to IsDate or IsNumeric for uniqueidentifier (SQL Server)?
Or is there anything equivalent to (C#) TryParse?
Otherwise I'll have to write my own function, but I want to make sure I'm not reinventing the wheel.
The scenario I'm trying to cover is the following:
SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
SQL Server 2012 makes this all much easier with TRY_CONVERT(UNIQUEIDENTIFIER, expression)
SELECT something
FROM your_table
WHERE TRY_CONVERT(UNIQUEIDENTIFIER, your_column) IS NOT NULL;
For prior versions of SQL Server, the existing answers miss a few points that mean they may either not match strings that SQL Server will in fact cast to UNIQUEIDENTIFIER without complaint or may still end up causing invalid cast errors.
SQL Server accepts GUIDs either wrapped in {} or without this.
Additionally it ignores extraneous characters at the end of the string. Both SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier) and SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier) succeed for instance.
Under most default collations the LIKE '[a-zA-Z0-9]' will end up matching characters such as À or Ë
Finally if casting rows in a result to uniqueidentifier it is important to put the cast attempt in a case expression as the cast may occur before the rows are filtered by the WHERE.
So (borrowing #r0d30b0y's idea) a slightly more robust version might be
;WITH T(C)
AS (SELECT '5D944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish')
SELECT CASE
WHEN C LIKE expression + '%'
OR C LIKE '{' + expression + '}%' THEN CAST(C AS UNIQUEIDENTIFIER)
END
FROM T
CROSS APPLY (SELECT REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]') COLLATE Latin1_General_BIN) C2(expression)
WHERE C LIKE expression + '%'
OR C LIKE '{' + expression + '}%'
Not mine, found this online... thought i'd share.
SELECT 1 WHERE #StringToCompare LIKE
REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
SELECT something
FROM table1
WHERE column1 LIKE '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]';
UPDATE:
...but I much prefer the approach in the answer by #r0d30b0y:
SELECT something
FROM table1
WHERE column1 LIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
I am not aware of anything that you could use "out of the box" - you'll have to write this on your own, I'm afraid.
If you can: try to write this inside a C# library and deploy it into SQL Server as a SQL-CLR assembly - then you could use things like Guid.TryParse() which is certainly much easier to use than anything in T-SQL....
A variant of r0d30b0y answer is to use PATINDEX to find within a string...
PATINDEX('%'+REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]')+'%',#StringToCompare) > 0
Had to use to find Guids within a URL string..
HTH
Dave
Like to keep it simple. A GUID has four - in it even, if is just a string
WHERE column like '%-%-%-%-%'
Though an older post, just a thought for a quick test ...
SELECT [A].[INPUT],
CAST([A].[INPUT] AS [UNIQUEIDENTIFIER])
FROM (
SELECT '5D944516-98E6-44C5-849F-9C277833C01B' Collate Latin1_General_100_BIN AS [INPUT]
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish'
) [A]
WHERE PATINDEX('[^0-9A-F-{}]%', [A].[INPUT]) = 0
This is a function based on the concept of some earlier comments. This function is very fast.
CREATE FUNCTION [dbo].[IsGuid] (#input varchar(50))
RETURNS bit AS
BEGIN
RETURN
case when #input like '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]'
then 1 else 0 end
END
GO
/*
Usage:
select [dbo].[IsGuid]('123') -- Returns 0
select [dbo].[IsGuid]('ebd8aebd-7ea3-439d-a7bc-e009dee0eae0') -- Returns 1
select * from SomeTable where dbo.IsGuid(TableField) = 0 -- Returns table with all non convertable items!
*/
DECLARE #guid_string nvarchar(256) = 'ACE79678-61D1-46E6-93EC-893AD559CC78'
SELECT
CASE WHEN #guid_string LIKE '________-____-____-____-____________'
THEN CONVERT(uniqueidentifier, #guid_string)
ELSE NULL
END
You can write your own UDF. This is a simple approximation to avoid the use of a SQL-CLR assembly.
CREATE FUNCTION dbo.isuniqueidentifier (#ui varchar(50))
RETURNS bit AS
BEGIN
RETURN case when
substring(#ui,9,1)='-' and
substring(#ui,14,1)='-' and
substring(#ui,19,1)='-' and
substring(#ui,24,1)='-' and
len(#ui) = 36 then 1 else 0 end
END
GO
You can then improve it to check if it´s just about HEX values.
I use :
ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL'
I had some Test users that were generated with AutoFixture, which uses GUIDs by default for generated fields. My FirstName fields for the users that I need to delete are GUIDs or uniqueidentifiers. That's how I ended up here.
I was able to cobble together some of your answers into this.
SELECT UserId FROM [Membership].[UserInfo] Where TRY_CONVERT(uniqueidentifier, FirstName) is not null
Use RLIKE for MYSQL
SELECT 1 WHERE #StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
In a simplest scenario. When you sure that given string can`t contain 4 '-' signs.
SELECT * FROM City WHERE Name LIKE('%-%-%-%-%')
In BigQuery you can use
SELECT *
FROM table
WHERE
REGEXP_CONTAINS(uuid, REPLACE('^00000000-0000-0000-0000-000000000000$', '0', '[0-9a-fA-F]'))