Sql Server 2008: How to order column with null values to show up in the end - sql

I am currently not able to sort the column to show up null values in the end
SELECT firstPart,secondPart FROM Exhibit_table d, ExhibitType a WHERE d.case_id ='13-05'
AND d.ExhibitTypeId = TypeId AND d.ComplianceNo = '0' and active = 1 order by CONVERT(INT, firstPart), secondPart
I have 2 columns firstpart and secondpart I need to sort it such a way that it shows in the following order
10
11
12 A
12 B
12 C
null null
null null
Any help is greatly appreciated

You can add a third sorting condition:
SELECT firstPart,secondPart
FROM Exhibit_table d, ExhibitType a
WHERE d.case_id ='13-05' AND d.ExhibitTypeId = TypeId AND d.ComplianceNo = '0' and active = 1
ORDER BY CASE WHEN firstPart IS NULL AND secondPart IS NULL THEN 0 ELSE 1 END,
CONVERT(INT, firstPart), secondPart
This will introduce a calculated field with value of 0 when both fields are NULL and value of 1 otherwise - and sort by that field. You can adjust that condition as needed.

Related

way to have query with case statement

I have table called Numbers in that column I have values from 0 - 10 but I like to keep value of 1-10 only change record of 0 too null
Case numbers
when 0
then ''
but I found this has changed all values and not values that have 0 is there way I can say else leave value as is?
Do you want this?
update t
set number = null
where number = 0;
Or as a select:
select t.*,
(case when number <> 0 then number end)
from t;
SELECT CASE WHEN [column] = 0 THEN NULL ELSE [column] END AS [SomeName]
FROM Numbers

Counting if data exists in a row

Hey guys I have the below sample data which i want to query for.
MemberID AGEQ1 AGEQ2 AGEQ2
-----------------------------------------------------------------
1217 2 null null
58458 3 2 null
58459 null null null
58457 null 5 null
299576 6 5 7
What i need to do is to lookup the table and if any AGEx COLUMN contains any data then it counts the number of times there is data for that row in each column
Results example:
for memberID 1217 the count would be 1
for memberID 58458 the count would be 2
for memberID 58459 the count would be 0 or null
for memberID 58457 the count would be 1
for memberID 299576 the count would be 3
This is how it should look like in SQL if i query the entire table
1 Children - 2
2 Children - 1
3 Children - 1
0 Children - 1
So far i have been doing it using the following query which isnt very efficient and does give incorrect tallies as there are multiple combinations that people can answer the AGE question. Also i have to write multiple queries and change the is null to is not null depending on how many children i am looking to count a person has
select COUNT (*) as '1 Children' from Member
where AGEQ1 is not null
and AGEQ2 is null
and AGEQ3 is null
The above query only gives me an answer of 1 but i want to be able to count the other columns for data as well
Hope this is nice and clear and thank you in advance
If all of the columns are integers, you can take advantage of integer math - dividing the column by itself will yield 1, unless the value is NULL, in which case COALESCE can convert the resulting NULL to 0.
SELECT
MemberID,
COALESCE(AGEQ1 / AGEQ1, 0)
+ COALESCE(AGEQ2 / AGEQ2, 0)
+ COALESCE(AGEQ3 / AGEQ3, 0)
+ COALESCE(AGEQ4 / AGEQ4, 0)
+ COALESCE(AGEQ5 / AGEQ5, 0)
+ COALESCE(AGEQ6 / AGEQ6, 0)
FROM dbo.table_name;
To get the number of people with each count of children, then:
;WITH y(y) AS
(
SELECT TOP (7) rn = ROW_NUMBER() OVER
(ORDER BY [object_id]) - 1 FROM sys.objects
),
x AS
(
SELECT
MemberID,
x = COALESCE(AGEQ1 / AGEQ1, 0)
+ COALESCE(AGEQ2 / AGEQ2, 0)
+ COALESCE(AGEQ3 / AGEQ3, 0)
+ COALESCE(AGEQ4 / AGEQ4, 0)
+ COALESCE(AGEQ5 / AGEQ5, 0)
+ COALESCE(AGEQ6 / AGEQ6, 0)
FROM dbo.table_name
)
SELECT
NumberOfChildren = y.y,
NumberOfPeopleWithThatMany = COUNT(x.x)
FROM y LEFT OUTER JOIN x ON y.y = x.x
GROUP BY y.y ORDER BY y.y;
I'd look at using UNPIVOT. That will make your wide column into rows. Since you don't care about what value was in a column, just the presence/absence of value, this will generate a row per not-null column.
The trick then becomes mashing that into the desired output format. It could probably have been done cleaner but I'm a fan of "showing my work" so that others can conform it to their needs.
SQLFiddle
-- Using the above logic
WITH HadAges AS
(
-- Find everyone and determine number of rows
SELECT
UP.MemberID
, count(1) AS rc
FROM
dbo.Member AS M
UNPIVOT
(
ColumnValue for ColumnName in (AGEQ1, AGEQ2, AGEQ3)
) AS UP
GROUP BY
UP.MemberID
)
, NoAge AS
(
-- Account for those that didn't show up
SELECT M.MemberID
FROM
dbo.Member AS M
EXCEPT
SELECT
H.MemberID
FROM
HadAges AS H
)
, NUMBERS AS
(
-- Allowable range is 1-6
SELECT TOP 6
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS TheCount
FROM
sys.all_columns AS SC
)
, COMBINATION AS
(
-- Link those with rows to their count
SELECT
N.TheCount AS ChildCount
, H.MemberID
FROM
NUMBERS AS N
LEFT OUTER JOIN
HadAges AS H
ON H.rc = N.TheCount
UNION ALL
-- Deal with the unlinked
SELECT
0
, NA.MemberID
FROM
NoAge AS NA
)
SELECT
C.ChildCount
, COUNT(C.MemberID) AS Instances
FROM
COMBINATION AS C
GROUP BY
C.ChildCount;
Try this:
select id, a+b+c+d+e+f
from ( select id,
case when age1 is null then 0 else 1 end a,
case when age2 is null then 0 else 1 end b,
case when age3 is null then 0 else 1 end c,
case when age4 is null then 0 else 1 end d,
case when age5 is null then 0 else 1 end e,
case when age6 is null then 0 else 1 end f
from ages
) as t
See here in fiddle http://sqlfiddle.com/#!3/88020/1
To get the quantity of persons with childs
select childs, count(*) as ct
from (
select id, a+b+c+d+e+f childs
from
(
select
id,
case when age1 is null then 0 else 1 end a,
case when age2 is null then 0 else 1 end b,
case when age3 is null then 0 else 1 end c,
case when age4 is null then 0 else 1 end d,
case when age5 is null then 0 else 1 end e,
case when age6 is null then 0 else 1 end f
from ages ) as t
) ct
group by childs
order by 1
See it here at fiddle http://sqlfiddle.com/#!3/88020/24

SQL - Find the binary representation from the place of '1's

It is really hard to find a good title for this.
Here is the question: I have a SELECT query GROUP BY a field which returns me up to three values (1,2,3). These values are representing the positions of '1' in a binary number.
In other words:
Query Output | Reult
0,1,2 | 7 (111)
1,2 | 6 (110)
3 | 1 (001)
- | 0 (000)
Ok, I know it is easy. But there are two constraints. First, I want a query not a function/store procedure. Second, the result should be a string (like '010') not the number.
I found the solution for integer value, but not the string (varchar)
SELECT COALESCE(sum(power(2, field)), 0) AS test FROM (
SELECT field FROM myTable GROUP BY field) a
I am using SQL server 2008, just in case.
I also have this solution, but this one cannot be extended to bigger number of outputs:
SELECT output =
CASE TEST
WHEN 0 THEN '000'
WHEN 1 THEN '001'
WHEN 2 THEN '010'
WHEN 3 THEN '011'
WHEN 4 THEN '100'
WHEN 5 THEN '101'
WHEN 6 THEN '110'
WHEN 7 THEN '111'
END
FROM(
select COALESCE(sum(power(2, 3 - field)), 0) as test from (
select field from myTable group by field) a) b
You can use binary and and string concatenation:
select (case when test&4 > 0 then '1' else '0' end) +
(case when test&2 > 0 then '1' else '0' end) +
(case when test&1 > 0 then '1' else '0' end)
from (select 6 as test) t;
If you are allergic to case statements, you could do this:
select CHAR(ascii(0) + (test&4)/4) +
CHAR(ascii(0) + (test&2)/2) +
CHAR(ascii(0) + (test&1)/1)
from (select 6 as test) t

query sql returning custom value

I have a table with 3 columns (containing Integer values that assume only values from 0 to 10). I want extract, with a single query, a table with 1 column. This column must assume a value based on the following logic:
If one of these three columns has value 0 ----> the value of column of table generated by query must be 0 too.
If none of the last three columns has value 0 ----> the value of column must assume the value 1.
You are looking for CASE construct or IF function:
SELECT CASE WHEN (t.field1 = 0 OR t.field2 = 0 OR t.field3 = 0) THEN 0
ELSE 1 END AS value
FROM t;
In this specific case you might also use the fact that any member being zero will zero the product:
SELECT CASE WHEN (t.field1*t.field2*t.field3 = 0) THEN 0 ELSE 1 END AS value
FROM t;
Or
SELECT IF((t.field1*t.field2*t.field3)=0, 0, 1) AS value FROM t;
This is a simple case statement. Assuming there are no NULL values, try this:
select (case when col1 = 0 or col2 = 0 or col3 = 0 then 0 else 1 end)
Try this
SELECT
CASE
WHEN column1 = 0 THEN 0
WHEN column2 = 0 THEN 0
WHEN column3 = 0 THEN 0
ELSE 1
END
FROM urtable

having issues sorting alpha numeric chars

I am trying to sort one column which have alphanumeric letters
see my query below
SELECT d.number
FROM table name d, table_name 2 a WHERE d.case_id ='11-41'
AND d.ExhibitTypeId = TypeId AND d.ComplianceNo = '0' and
active = 1 and number is not null order by case
when ISNUMERIC(d.number) = 1 then right('0000000000'+d.number+'0',10)
else right('0000000000'+d.number,10)
end
This is the output
1
2
3
11
12
2A1
I want this output instead
1
2
2A1
3
11
12
Any help regarding this is greatly appreciated.
If(ISNUMERIC(LEFT(case,2)
BEGIN
order by case
END
else
BEGIN
order by LEFT(case,1), LEFT(case,2)
END
Assuming SQL Server this may work with some tweaks
SELECT
d.number
FROM
table name d,
table_name 2 a
WHERE
d.case_id ='11-41'
AND
d.ExhibitTypeId = TypeId
AND
d.ComplianceNo = '0'
and
active = 1
and number is not null
order by
Convert(int, LEFT(number, Case
When PATINDEX('%[^0-9]%', number) > 0 Then PATINDEX('%[^0-9]%', number) - 1
Else LEN(number)
End)
),
LEN(Number)