SQl sort data by multiple columns - c#

I need to sort the following table from the query:
SELECT *
FROM Likelihood WITH (NOLOCK)
INNER JOIN Diagnosis ON Diagnosis.DiagnosisID = Likelihood.DiagnosisID
WHERE Likelihood.SessionID = (6768)
ORDER BY Likelihood.Percentage DESC
**Percentage Diagnosis Level**
100 F43.10 HIGH
83.333336 F84.5 HIGH
75 F40.9 HIGH
66.666664 F90.0 MEDIUM
50 F51.09 MEDIUM
First sort by Likelihood.Percentage in descending.
Then when Level = 'HIGH' then sort by Diagnosis ascending. Diagnosis column is a string.
When Level = 'MEDIUM' then sort by Diagnosis ascending
The resulting table should be:
**Percentage Diagnosis Level**
100 F43.10 HIGH
75 F40.9 HIGH
83.333336 F84.5 HIGH
50 F51.09 MEDIUM
66.666664 F90.0 MEDIUM
I tried this query, but did not get the results:
SELECT *
FROM Likelihood WITH (NOLOCK)
INNER JOIN Diagnosis ON Diagnosis.DiagnosisID = Likelihood.DiagnosisID
WHERE Likelihood.SessionID = (6768)
ORDER BY
case when Level='HIGH' and Percentage > 70 then Diagnosis.Diagnosis end
, case when Level='Medium' and Percentage between 50 and 69 then Diagnosis.Diagnosis end
, Likelihood.Percentage DESC

If I understood correctly, you simply need to specify a few order by conditions. First is Percentage, then Level (HIGH should be before the MEDIUM because of alphabetic sorting), and then by Diagnosis.
So,
order by
Percentage DESC,
Level ASC,
Diagnosis ASC;

it is an example for multi column sort :
SELECT city,first_name,last_name
FROM
sales.customers
ORDER BY
city DESC,
first_name ASC;
for more guide check below link
https://www.sqlservertutorial.net/sql-server-basics/sql-server-order-by/

Related

Find values based on one column table from another table.Pivot

Help needed.
I have three tables
Building_master - columns: BuildingCode, Building Name
Floor_master - columns: FloorCode, Floor Name, BuildingCode
Room_Master - columns: RoomCode, RoomName, RoomFloor, RoomBulding
I want to fill the GridView when I select Building Name from Building_master table where the output will be something like below
Building Name: A
Floor
1 Room 101 Room 102 Room 103 Room 104
2 Room 201 Room 202 Room 203
3 Room 301 Room 302 Room 303 Room 304
Kindly help to create a SQL query for the desired output
To pivot over a fixed number of columns (that is, the maximum number of rooms per floor), you can join, then use window functions and conditional aggregation:
select
building_name,
floor_name,
max(case when rn = 1 then room_name end) room1,
max(case when rn = 2 then room_name end) room2,
max(case when rn = 3 then room_name end) room3
from (
select
b.building_code,
b.building_name,
f.floor_code,
f.floor_name,
r.room_name,
row_number() over(
partition by b.building_code, f.floor_code order by r.room_code
) rn
from building_master b
inner join floor_master f
on f.building_code = b.building_code
inner join room_master r
on r.room_floor = f.floor_code
and r.room_building = b.building_code
) t
group by b.building_code, b.building_name, f.floor_code, f.floor_name
I had to make a few guesses about the relationships in your schema, that you might need to review.
You can handle more rooms by floor by adding more max() expressions to the outer select.

I need to make a data row which contains the most appear of occurences using 2 tables

I need to make a query that provides me the most common values over columns,
the ones with the most occurrences.
For example:
Name Grade Gender
--------------------------
Jeff 100 Male
Daniel 100 Male
Linda 80 Female
Jeff 90 Male
The query will provide me a datarow with Name - Jeff Grade - 100 Gender - Male
The query I have by far is this:
SELECT
PhonesTBL.OperatingSystem, PhonesTBL.Memory,
PhonesTBL.BatterySize, PhonesTBL.CameraQuality, PhonesTBL.Processor,
PhonesTBL.ScreenSize, PhonesTBL.PhoneType
FROM
PhonesTBL
INNER JOIN
HistoryTBL ON PhonesTBL.PhoneID = HistoryTBL.PhoneID
WHERE
UserID = Uid
GROUP BY
OperatingSystem, Memory, BatterySize, CameraQuality, Processor,
ScreenSize, PhoneType
ORDER BY
COUNT(*) DESC
but it returns just distinct of values I want.
Looking for help , Ohad
Your question doesn't really make sense. You have sample data that has nothing to do with your query. Let me use the sample data.
In MS Access, this is most simply done by putting the mode (the statistical name for what you want) in separate rows:
(select top (1) "name" as which, name
from t
group by name
order by count(*) desc, name
) union all
(select top (1) "grade" as which, grade
from t
group by grade
order by count(*) desc, grade
) union all
(select top (1) "gender" as which, gender
from t
group by gender
order by count(*) desc, gender
);

Faster way to insert records into database

So I currently have a database table of about 70,000 names. What I want to do is take 3000 random records from that database and insert them into another table where each name has a row for all the other names. In other words, the new table should look like this:
John, jerry
john, alex
john, sam
jerry, alex
jerry, sam
alex, sam
This means that I should be adding summation n rows to the table. My current strategy is to use two nested for loops to add these rows one at a time and then removing the first name from the list of names to add in order to ensure I dont have a duplicate record with different ordering.
My question is this: is there a faster way to do this, perhaps through parallel for loops or PLINQ or some other option that I a have not mentioned?
Given a table "Names" with an nvarchar(50) column "Name" with this data:
Adam
Bob
Charlie
Den
Eric
Fred
This query:
-- Work out the fraction we need
DECLARE #frac AS float;
SELECT #frac = CAST(35000 AS float) / 70000;
-- Get roughly that sample size
WITH ts AS (
SELECT Name FROM Names
WHERE #frac >= CAST(CHECKSUM(NEWID(), Name) & 0x7FFFFFFF AS float) / CAST (0X7FFFFFFF AS int)
)
-- Match each entry in the sample with all the other entries
SELECT x.Name + ', ' + y.Name
FROM ts AS X
CROSS JOIN
Names AS Y
WHERE x.Name <> y.Name
produces results of the form
Adam, Bob
Adam, Charlie
Adam, Den
Adam, Eric
Adam, Fred
Charlie, Adam
Charlie, Bob
Charlie, Den
Charlie, Eric
Charlie, Fred
Den, Adam
Den, Bob
Den, Charlie
Den, Eric
Den, Fred
The results will vary by run; a sample of 3000 out of 70000 will have approximately 3000 * 70000 result rows. I used 35000./70000 because the sample size I used was only 6.
If you want only the names from the sample used, change CROSS JOIN Names AS Y to CROSS JOIN ts AS Y, and there will then be approximately 3000 * 3000 result rows.
Reference: The random sample method was taken from the section "Important" in Limiting Result Sets by Using TABLESAMPLE.
You will need to figure out the random part
select t1.name, t2.name
from table t1
join table t2
on t1.name < t2.name
order by t1.name, t2.name
You need to materialize the newid
declare #t table (name varchar(10) primary key);
insert into #t (name) values
('Adam')
, ('Bob')
, ('Charlie')
, ('Den')
, ('Eric')
, ('Fred');
declare #top table (name varchar(10) primary key);
insert into #top (name)
select top (4) name from #t order by NEWID();
select * from #top;
select a.name, b.name
from #top a
join #top b
on a.name < b.name
order by a.name, b.name;
Using a Number table to simulate names.
single query, using a triangular join
WITH all_names
AS (SELECT n,
'NAME_' + Cast(n AS VARCHAR(20)) NAME
FROM number
WHERE n < 70000),
rand_names
AS (SELECT TOP 3000 *
FROM all_names
ORDER BY Newid()),
ordered_names
AS (SELECT Row_number()
OVER (
ORDER BY NAME) rw_num,
NAME
FROM rand_names)
SELECT n1.NAME,
n2.NAME
FROM ordered_names n1
INNER JOIN ordered_names n2
ON n2.rw_num > n1.rw_num

How to solve the subquery

I have data like this
Sr_No/ AccessionNo / Roll_nO / Price
---------------------------------------
1 / 101 / 45 / 1000
2 / 102 / 46 / 2000
3 / 101 / 43 / 500
I have written this query
select *
from Circulation
where MAX(sr_no) in (select *
from circulation
where accessionno = #accessionno)
I want to get values where the accession no is given by the textbox and it should be the the maximum value of Sr_No and for info Sr_NO is auto incremented.
My query is not working
I am a student and started c# quite a few months ago
Sorry for my bad english
I got this error
An aggregate may not appear in the WHERE
clause unless it is in a subquery contained in a HAVING clause or a select list, and the
column being aggregated is an outer reference.
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I want that when I type 101 as accession no. so it will return this info
3 / 101 / 43 / 500
You probably wanted something like this:
SELECT *
FROM Circulation
WHERE sr_no = (SELECT MAX(sr_no)
FROM circulation
WHERE accessionno = #accessionno)
You want to select the row(s) from Circulation where the sr_no column equals the maximum of all sr_no values in your table - right?
SQL Server supports Common Table Expression and Window Function. ROW_NUMBER() will rank the SR_NO in descending order for every AccessionNo. So the value of 1 is given for the highest SR_NO per AccessionNo.
WITH records
AS
(
SELECT Sr_No, AccessionNo, Roll_nO, Price,
ROW_NUMBER() OVER(PARTITION BY AccessionNo ORDER BY Sr_No DESC) rn
FROM Circulation
)
SELECT Sr_No, AccessionNo, Roll_nO, Price
FROM records
WHERE rn = 1
But if an AccessionNo is already give, a simple TOP will do your job.
SELECT TOP 1 *
FROM Circulation
WHERE accessionno = #accessionno
ORDER BY Sr_no DESC
SELECT TOP 1 *
FROM Circulation
WHERE accessionno = #accessionno
ORDER BY Sr_no DESC
Also, it's best not to use SELECT * and instead use the column names.

Removing Duplicate row from a table based on one column

I created a table with multiple inner joins from 4 tables but the results brings back duplicate records. Here code that I am using
SELECT tblLoadStop.LoadID,
tblCustomer.CustomerID,
tblLoadMaster.BillingID,
tblLoadMaster.LoadID,
tblLoadMaster.PayBetween1,
LoadStopID,
tblLoadMaster.Paybetween2,
tblStopLocation.StopLocationID,
tblStopLocation.city,
tblStopLocation.state,
tblStopLocation.zipcode,
tblLoadSpecifications.LoadID,
tblLoadSpecifications.LoadSpecificationID,
Picks,
Stops,
Typeofshipment,
Weight,
LoadSpecClass,
Miles,
CommodityList,
OriginationCity,
OriginationState,
DestinationCity,
DestinationState,
LoadRate,
Status,
CompanyName,
Customerflag,
tblCustomer.CustomerID,
tblCustomer.AddressLine1,
tblCustomer.City,
tblCustomer.State,
tblCustomer.Zipcode,
CompanyPhoneNumber,
CompanyFaxNumber,
SCAC,
tblLoadMaster.Salesperson,
Change,
StopType
FROM tblLoadMaster
INNER JOIN tblLoadSpecifications
ON tblLoadSpecifications.LoadID = tblLoadMaster.LoadID
INNER JOIN tblLoadStop
ON tblLoadStop.LoadID = tblLoadMaster.LoadID
INNER JOIN tblStopLocation
ON tblStopLocation.StopLocationID = tblLoadStop.StopLocationID
INNER JOIN tblCustomer
ON tblCustomer.CustomerID = tblLoadMaster.CustomerID
WHERE tblLoadMaster.Phase LIKE '%2%'
ORDER BY tblLoadMaster.LoadID DESC;
This is the result that I get
Load ID Customer Salesperson Origin Destination Rate
-------------------------------------------------------------------------
13356 FedEx Alex Duluth New York 300
13356 FedEx Steve Florida Kansas 400
I only want the first row to show,
13356 FedEx Alex Duluth New York 300
and remove the bottom row,
13356 FedEx Steve Florida Kansas 400
The tblLoadStop Table has the duplicate record with a duplicate LoadID from tblloadMaster Table
One approach would be to use a CTE (Common Table Expression) if you're on SQL Server 2005 and newer (you aren't specific enough in that regard).
With this CTE, you can partition your data by some criteria - i.e. your LoadID - and have SQL Server number all your rows starting at 1 for each of those "partitions", ordered by some criteria (you're not very clear on how you decide which row to keep and which to ignore in your question).
So try something like this:
;WITH CTE AS
(
SELECT
LoadID, Customer, Salesperson, Origin, Destination, Rate,
RowNum = ROW_NUMBER() OVER(PARTITION BY LoadID ORDER BY tblLoadstopID ASC)
FROM
dbo.tblLoadMaster lm
......
WHERE
lm.Phase LIKE '%2%'
)
SELECT
LoadID, Customer, Salesperson, Origin, Destination, Rate
FROM
CTE
WHERE
RowNum = 1
Here, I am selecting only the "first" entry for each "partition" (i.e. for each LoadId) - ordered by some criteria (updated: order by tblLoadstopID - as you mentioned) you need to define in your CTE.
Does that approach what you're looking for??

Categories