here is my table description:
Table Name : Orders
Columns : ID, NO, Quantity, Base, Code
First my query should check the value of Code, if value of Code is 'B' then OUTPUT VALUE should be Code+Base if it is not 'B' then OUTPUT VALUE should be Code+Quantity
the obtained rows again will be filtered by using where clause where ID='' and quantity=''
How can I form this complex query, any ideas ?...
Modified Answer
Something bothered me about my original post (see below, but do not use) so I went back to check. If Code is 'B' (therefore a varchar) and Quantity is an integer, then SQL will not let you add them for obvious reasons and will not do an implicit conversion for you (at least it did not do it for me). So I had to convert Quantity to a varchar to be able to use it.
Look at the following working code built on SQL Server 2008
DECLARE #MyTable TABLE
(
ID int identity (1, 1),
Num int,
Quantity int,
Base varchar (1),
Code varchar (1)
)
INSERT INTO #MyTable VALUES
(1, 1, 'a', 'A')
, (2, 2, 'b', 'B')
, (3, 3, 'c', 'C')
, (4, 4, 'd', 'D')
, (5, 5, 'e', 'E')
SELECT * FROM #MyTable
SELECT
CASE WHEN Code = 'B' THEN Code+Base
ELSE Code+CONVERT (VarChar, Quantity)
END AS OutputValue
FROM #MyTable
Original Answer (do not use)
try the following
SELECT CASE WHEN Code = 'B' THEN Code+Base ELSE Code+Quantity END AS OutputValue
FROM MyTable
WHERE ID = #Id
and Quantity = #Quantity
SELECT CASE Code WHEN 'B' THEN Code + Base ELSE Code + Quantity END As OutputValue
FROM Orders
WHERE ID = #id AND Quantity = #quantity
SELECT
(
CASE Code
WHEN CODE = 'B' THEN Code+Base
ELSE Code+Quantity
END
) AS OutputValue
FROM Orders
WHERE ID = '' AND Quantity=''
Related
I have a question on how to write a single query to insert and update. Below is the scenario. I am trying to use 1 query for the part that is enclosed in (-----)
CREATE TABLE #TEMP
(
Ref VARCHAR(10),
Num INT,
[Status] VARCHAR(3)
)
INSERT INTO #TEMP
VALUES ('A123', 1, 'A3'), ('A123', 2, 'A3'), ('A123', 3, 'A3'),
('B123', 1, 'A1'), ('B123', 2, 'A3'),
('C123', 1, 'A1'), ('C123', 2, 'A2'), ('C123', 3, 'A3');
SELECT
Ref,
CASE WHEN A.TotalCount = A.DenialCount THEN 1 ELSE 0 END IsDenial
--CASE WHEN A.TotalCount <> A.DenialCount Then 1 else 0 end IsApproval
INTO
#TEMP1
FROM
(SELECT
Ref, COUNT(Num) TotalCount,
SUM(CASE WHEN [Status] = 'A1' THEN 1 ELSE 0 END) ApprovedCount,
SUM(CASE WHEN [Status] = 'A2' THEN 1 ELSE 0 END) PartialApprovalCount,
SUM(CASE WHEN [Status] = 'A3' THEN 1 ELSE 0 END) DenialCount
FROM
#temp
GROUP BY
Ref) A
UPDATE A
SET A.[Status] = CASE WHEN IsDenial = 1 THEN 'A3' ELSE 'A1' END
FROM #TEMP A
JOIN #TEMP1 B ON A.Ref = B.Ref
SELECT * FROM #TEMP
SELECT * FROM #TEMP1
DROP TABLE #TEMP
DROP TABLE #TEMP1
Any help would be appreciated.
"INSERT into 1 table and UPDATE another table in one query"
Nope. Some DBMSes support the idea of 'upsert' but that's insert/update in a single table.
Your looking for the MERGE statment. However I see several issues with the SQL in your post. In short it is generally more efficient to use set theory instead of thinking of optimisations per statement.
Rather than update, why not join in the data thats inserted into temp into the second query and produce the result you require?
hint ' SELECT 'ABC' as a, '123' as b, 456 as c UNION '
I need show sum col(item) under col with SQL code ? it's possible
Code item
---- ----
1 30
3 40
4 50
9 80
---- ----
Total 200
Use Rollup to get the summary row
SELECT CASE
WHEN Grouping(code) = 1 THEN 'Total'
ELSE Cast(code AS VARCHAR(50))
END,
Sum(item)
FROM Yourtable
GROUP BY code WITH rollup
DECLARE #Table1 TABLE
(Code int, item int)
;
INSERT INTO #Table1
(Code, item)
VALUES
(1, 30),
(3, 40),
(4, 50),
(9, 80)
;
Script :
select Code , sum(item)item
from #Table1
group by GROUPING SETS((Code) , ())
order by Code DESC
select * from (select * from #Table1
union
select null, sum(item) item from #Table1)a
order by item
Select
Code,
item
from
# table_name
Union All
select
Null,
sum(item)item
from
# table_name
As we are using union all so distinct and order by operation will be saved.
I am stuck on converting a varchar column schedule containing the following data 0, 1, 2, 3,4,8,9,10,11,12,15,16,17,18,19 to INT. I know, please don't ask why this schedule column was not created as INT initially, long story.
So I tried this, but it doesn't work. and give me an error:
select CAST(schedule AS int) from shift_test:
the query should check if the numbers representing days are found in the schedule filed using the sql code below
select empid, case when ((DateDiff(hour,'01-01-2014 07:00' , '01-01-2014 00:00')/ 24 )% 15) in ( CAST(schedule AS int))
then 'A' else '*' end as shift_A from Shift_test
After executing i get this error.
Conversion failed when converting the varchar value to int.
Any help will be appriciated
Use ISNUMERIC() test if you are using version 2008 or 2008R2. In SQL SERVER 2012 you can use TRY_CAST() function, which checks if the data conversion is allowed for given literal.
Mock up code for SQL Server 2008/R2:
Select col1, col2,
case
when <condition> and isnumeric(col2) then cast(col2 as int)
else <do whatever...>
end
as converted_col2
from <yourtable>;
For SQL Server 2012:
Select col1, col2,
case
when <condition> then try_cast(col2 as int)
else <do whatever...>
end
as converted_col2
from <yourtable>;
Example with SQl Server 2008
declare #T table (empid int, schedule varchar(2)) ;
insert into #T(empid, schedule) values (1, '1');
insert into #T(empid, schedule) values (2, '2');
insert into #T(empid, schedule) values (3, '03');
insert into #T(empid, schedule) values (4, '4');
insert into #T(empid, schedule) values (5, '05');
insert into #T(empid, schedule) values (6, 'A');
select empid,
case
when ISNUMERIC(schedule) = 1
and ((DateDiff(hour,'01-01-2014 07:00' , '10-01-2014 00:00')/ 24 )% 15)
in ( CAST(schedule AS int)) then 'A'
else '*'
end
as shift_A
from #T;
# Binaya Ive added my code for more help.
The schedule column contain (0, 1, 2, 3,4,8,9,10,11,12,15,16,17,18,19) which is varchar.
i want to output A if after this calculation ((DateDiff(hour,'01-01-2014 07:00',startdate)/ 24 )% 15) the result is found in the schedule column else if after the calculation and the result is not found output *
;with Shift_runover (shift_code,schedule,endd,startdate)
-- Start at the beginning of shift.
as
(select shift_code,schedule,Cast(end_date as DateTime) as endd,Cast(start_date as DateTime)as startdate from dbo.Shift_test
union all
-- Add hours up to the desired end date.
select shift_code,schedule,endd,DateAdd(hour, 1,startdate)from Shift_runover where startdate<=endd),
Extendedsamples as
(
-- Calculate the number of days since the beginning of the first shift on 1/1/2014.
select shift_code,schedule,startdate,DateDiff(hour,'01-01-2014 07:00',startdate)/ 24 as Days from Shift_runover ),
Shifts as
(
-- the schedule column contain (0, 1, 2, 3,4,8,9,10,11,12,15,16,17,18,19) which is varchar.
-- i want to output A if ((DateDiff(hour,'01-01-2014 07:00',startdate)/ 24 )% 15) is found in the schedule colume
select *,
case when (DateDiff(hour,'01-01-2014 07:00',startdate)/ 24 )% 15 in(schedule)
then 'A' else '*' end as shift_A
from ExtendedSamples
)
select *
from Shifts
option ( maxrecursion 0 )
Good Day,
So I'm stuck with a SQL query in which the table I'm querying has multiple sequential columns, such as
Property1,
Property2,
Property3,
Property4,
Property5
..etc
Now there are about 64 columns descending in the same naming convention.
They are varchar of type and marked by a single "Y" or "N" stating boolean function.(Not my design)
Now where I'm stuck is that in my query I need to return the First Property column that's marked as "Y" in a single record..
I've searched around but could not have come upon the same question asked elsewhere.. Maybe I'm just missing it?
It would really be appreciated should anyone have a hint for me to follow or so on?
Thanks in advance!
The basic idea is to concatenate all fields in one string and then find the index of the first occurrence of Y and form a field label as PROPERTY+FIRST OCCURRENCE INDEX.
If Y is not found then PROPERTY0 appears in this query you can handle this with CASE statement for example.
SQLFiddle demo
select id,
'PROPERTY'+
CONVERT(VARCHAR(10),CHARINDEX('Y',property1+property2+property3))
from T
You could consider unpivot
declare #t table(id int identity(1,1), Property1 char(1),
Property2 char(1),
Property3 char(1),
Property4 char(1),
Property5 char(1))
insert #t values('N', 'Y', 'Y', 'N', 'Y')
insert #t values('N', 'N', 'Y', 'N', 'Y')
insert #t values('N', 'N', 'N', 'N', 'Y')
;with a as
(
select *, row_number() over (partition by id order by id) position from #t
unpivot
(Property FOR colname IN
([Property1], [Property2], [Property3], [Property4],
[Property5]/*include more properties here*/) ) AS unpvt
)
select t.id, coalesce(colname, 'Not found') colname
from #t t
outer apply
(select top 1 id, colname, position
from a where Property = 'Y'
and t.id = id
order by id
) x
that design is horrible. But this should work:
SELECT CASE WHEN Property1 = 'Y' THEN 'Property1'
WHEN Property2 = 'Y' THEN 'Property2'
[...]
ELSE 'None'
END
Try this:
select
CASE WHEN QryGroup1 = 'Y' then 'QryGroup1'
WHEN QryGroup2 = 'Y' then 'QryGroup2'
WHEN QryGroup3 = 'Y' then 'QryGroup3'
WHEN QryGroup10 = 'Y' then 'QryGroup10'
else ''
end as [SelectedBP]
from OCRD
This could work as well:
SELECT CHARINDEX ( 'Y' , CONCAT(Property1,Property2,...,Property64) )
It returns a numeric index of the column and it has the advantage that you can define a function based index to speed up the query.
Consider the below
Declare #t table(Val int, name varchar(100))
Insert into #t select 1,'name1'
union all select 1,'name2'
union all select 2,'name3'
union all select 3,'name4'
If I want to get the records pertainig to Val 1 or 2 the choice is an IN clause. But we have some condition based on which the values needs to be choosen. Henceforth, we are going ahead with CASE approach as under
declare #type int = 1
select *
from #t
where val = case when #type =1 then 1 end or
val = case when #type =1 then 2
end
It works fine as select * from #t where val in (1,2)(we cannot use this as the value has to be determined at runtime and we are not using any dynamic query). Is there any other way to simulating the IN clause?
This is just for the sake of knowledge.
Thanks
Assuming that your code takes a single values as a parameter, but that the value relates to a list of values, you could just use a mapping table...
CREATE PROCEDURE pseudo_in_clause (#type INT)
AS
DECLARE #map TABLE (
type INT,
val INT,
PRIMARY KEY (type, val)
)
INSERT INTO #map (type, val) VALUES (1, 1),
(1, 2),
(2, 3)
SELECT
*
FROM
yourTable AS data
INNER JOIN
#map AS map
ON data.val = map.val
WHERE
map.type = #type
The map could be a permanent table, a temp table such as above, function, etc.
Alternatively, you can still use an IN clause in the CASE statement...
SELECT
*
FROM
yourTable AS data
WHERE
CASE WHEN #type = 1 AND data.val IN (1,2) THEN 1
WHEN #type = 2 AND data.val IN (3,4) THEN 1
ELSE 0
END = 1
Personally I prefer the JOIN version.
Do you have to use CASE? This should work as well:
…
WHERE #type = 1 AND data.val IN (1, 2)
OR #type = … AND data.val IN (…)
OR …
Although I must say that I like #Dems's suggestion about using a join best of all. Note that you could use an inline table instead of a table variable, thus making the entire thing a single query:
SELECT *
FROM yourTable AS data
INNER JOIN (
VALUES
(1, 1),
(1, 2),
(2, 3)
) AS map ON data.val = map.val
WHERE map.type = #type