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.
Related
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/
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
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.
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??
it is possible that similar questions have been asked earlier, but I can't find them. So here is my objective.
I have three tables like 1.Bill 2.BillDetail 3.ExpenseInfo. Table "Bill" have a primary key named "BillID" which is foreign key of table "BillDetail". Similarly, table "ExpenseInfo" have a PK "ExpenseID" which is also FK to "BillDetail". Data kept in these tables are in below format. For 1 entry in Bill table, there might be 1 or more rows in BillDetail table where each row contains 1 ExpenseID. Now I want to write a query which will select data something like-
BillID BillDate Fuel Food Travel
1 28-02-12 10 20 50
here Fuel, Food, Travel are various expense types saved in table "ExpenseInfo". I have tried below. Am I going the right way or some other smart way exists to do this?
SELECT *
FROM t_BillInfoDetail a
LEFT OUTER JOIN
(
SELECT ISNULL(ExpenseID,0) AS ExpenseID, ISNULL(ExpenseName,'N/A') AS ExpenseName
FROM t_expenseinfo
WHERE ExpenseID=1
) AS LocalTravel ON a.ExpenseID = LocalTravel.ExpenseID
Newly Added
Thank you all for your replies.
Currently I am doing as below for my purpose. Hope you like it.
SELECT
BI.* , BID.ExpenseID, BID.BillDescription, BID.LocalTravel, BID.LocalHotel, BID.Fuel
FROM
(
SELECT *
FROM t_BillInfo
WHERE BillID = 1
) AS BI
LEFT OUTER JOIN
(
SELECT BillID, BillDescription, ExpenseID,
ISNULL(SUM(CASE ExpenseID WHEN 1 THEN Amount ELSE 0 END), 0) AS LocalTravel,
ISNULL(SUM(CASE ExpenseID WHEN 2 THEN Amount ELSE 0 END), 0) AS LocalHotel,
ISNULL(SUM(CASE ExpenseID WHEN 3 THEN Amount ELSE 0 END), 0) AS Fuel
FROM t_BillInfoDetail
GROUP BY BillID, BillDescription, ExpenseID
) AS BID ON BI.BillID = BID.BillID
Probably I'm not getting the question right, but as I see it you have 3 tables joined like a "chain" Bill -HAS_MANY> BillDetail -HAS_ONE> ExpenseInfo.
If that is the case you just have to join the tables with inner joins requesting the data from each of the tables you require. You didn't provide your table structure but should be done this way:
select b.aBillField, bd.aBillDetailField, ei.aExpenseInfoField from bill b
inner join billDetail bd
on b.billID = bd.billFK
inner join expenseInfo ei
on ei.expenseFK = bd.billDetailId
where expenseId = 1
Of course, replace the invented fields with the corresponding ones.
In case if u need a store procedure,and if u can be more clear in your question we can easily answer you...for now you try this
create procedure [dbo].[SP_GetInfo]
(
#ExpenseID int
)
as
begin
select Bill .BillID , BillDetail .BillDate , ExpenseInfo.Fuel
from Bill , BillDetail , ExpenseInfo
where Bill .BillID = BillDetail .BillID
AND ExpenseInfo.ExpenseID =#ExpenseID
GO
try this if u have any error please ask me....
If I read correctly, you want to PIVOT your data in the ExpenseInfo table. Try the following:
SELECT BillID,
BillDate,
Fuel,
Food,
Travel
FROM (SELECT BillID,
BillDate,
ExpenseName,
ExpenseAmount
FROM Bill AS B
INNER JOIN BillDetail BD
ON B.BillID = BD.BillID
INNER JOIN ExpenseInfo EI
ON BD.ExpenseID = EI.ExpenseID) AS up PIVOT (SUM( ExpenseAmount
) FOR
ExpenseName IN (Fuel, Food, Travel)) AS pvt
ORDER BY BillID
This is what I am using. It fulfills my requirement.
SELECT
BI.* , BID.ExpenseID, BID.BillDescription, BID.LocalTravel, BID.LocalHotel, BID.Fuel
FROM
(
SELECT *
FROM t_BillInfo
WHERE BillID = 1
) AS BI
LEFT OUTER JOIN
(
SELECT BillID, BillDescription, ExpenseID,
ISNULL(SUM(CASE ExpenseID WHEN 1 THEN Amount ELSE 0 END), 0) AS LocalTravel,
ISNULL(SUM(CASE ExpenseID WHEN 2 THEN Amount ELSE 0 END), 0) AS LocalHotel,
ISNULL(SUM(CASE ExpenseID WHEN 3 THEN Amount ELSE 0 END), 0) AS Fuel
FROM t_BillInfoDetail
GROUP BY BillID, BillDescription, ExpenseID
) AS BID ON BI.BillID = BID.BillID