2021-03-09 SQL-Intermediate

You can use CHARINDEX to find a specific character or pattern within a column.
CHARINDEX returns the position of the keyword, for example, the "weather" appears at 29th (caculation includes space (空格键)), so it finally returns 29

Use substring:
SUBSTRING(Expression, Starting Position, Total Length)
We used SUBSTRING, passed in the description column, told the function to begin counting from the 15th character, for the remaining length of the string, which ensured we returned each remaining cause of outage.

About how to solve this problem:
start_number is a number
now I want to extract additional information of the description.
now I want the string except the "weather"
substring(description, ?, len(description)) ? should be the starting position

Sometimes you might want to 'save' the results of a query so you can do some more work with the data. You can do that by creating a temporary table that remains in the database until SQL Server is restarted.

SELECT  album.title AS album_title,
  artist.name as artist,
  MAX(track.milliseconds / (1000 * 60) % 60 ) AS max_track_length_mins
-- Name the temp table #maxtracks
INTO #maxtracks
FROM album
-- Join album to artist using artist_id
INNER JOIN artist ON album.artist_id = artist.artist_id
-- Join track to album using album_id
INNER JOIN track ON track.album_id=album.album_id
GROUP BY artist.artist_id, album.title, artist.name,album.album_id
-- Run the final SELECT query to retrieve the results from the temporary table
SELECT album_title, artist, max_track_length_mins
FROM  #maxtracks
ORDER BY max_track_length_mins DESC, artist;

Replace the null value:

-- Check the IncidentState column for missing values and replace them with the City column
SELECT IncidentState, ISNULL(IncidentState,"City") AS Location
FROM Incidents
-- Filter to only return missing values from IncidentState
WHERE IncidentState IS NULL

What if you want to replace missing values in one column with another and want to check the replacement column to make sure it doesn't have any missing values? To do that you need to use the COALESCE statement.

-- Replace missing values 
SELECT Country, coalesce(IncidentState, City, 'Unknown') AS Location
FROM Incidents
WHERE Country IS NULL

Create a new column, SourceCountry, defined from these cases:
When Country is 'us' then it takes the value 'USA'.
Otherwise it takes the value 'International'.

SELECT Country, 
       CASE WHEN Country = 'us'  THEN 'USA'
       ELSE 'International'
       END AS SourceCountry
FROM Incidents

Use case when:

- Complete the syntax for cutting the duration into different cases
SELECT DurationSeconds, 
-- Start with the 2 TSQL keywords, and after the condition a TSQL word and a value
      case when (DurationSeconds <= 120) then 1
-- The pattern repeats with the same keyword and after the condition the same word and next value          
       when (DurationSeconds > 120 AND DurationSeconds <= 600)then 2
-- Use the same syntax here             
        when (DurationSeconds > 601 AND DurationSeconds <= 1200) then  3
-- Use the same syntax here               
        when (DurationSeconds > 1201 AND DurationSeconds <= 5000) then 4
-- Specify a value      
       ELSE 5 
       END AS SecondGroup   
FROM Incidents

Use count just after "select" and then use group by

-- Write a query that returns an aggregation 
SELECT MixDesc, SUM(Quantity) AS Total
FROM Shipments
-- Group by the relevant column
GROUP BY MixDesc

Use DATEDIFF and DATEADD
SELECT DATEADD(DD, -30, '2020-06-21')
DATEDIFF (datepart, startdate, enddate)

- Return the DeliveryDate as 5 days after the ShipDate
SELECT OrderDate, 
       DATEADD(DD,5,ShipDate) AS DeliveryDate
FROM Shipments

Use ABS() to return non-negative values
Use SQUARE() and SQRT to calculate square and square root

use derived tabel:
calculate the maximum value of the blood glucose level for each record by age.

SELECT a.RecordId, a.Age, a.BloodGlucoseRandom, 
-- Select maximum glucose value (use colname from derived table)
       b.MaxGlucose
FROM Kidney a
-- Join to derived table
JOIN (SELECT Age, MAX(BloodGlucoseRandom) AS MaxGlucose FROM Kidney GROUP BY Age) b
-- Join on Age
ON a.Age = b.Age

Another sample to select the highest bloodpressure grouped by their age:

SELECT *
FROM Kidney a
-- Create derived table: select age, max blood pressure from kidney grouped by age
JOIN (select age,max(BloodPressure) AS MaxBloodPressure from kidney group by age) b
-- JOIN on BloodPressure equal to MaxBloodPressure
ON a.BloodPressure=b.MaxBloodPressure
-- Join on Age
AND a.Age=b.Age

UseCTE() to simplify the sql sentences:

-- Specify the keyowrds to create the CTE
with BloodGlucoseRandom (MaxGlucose) 
as (SELECT MAX(BloodGlucoseRandom) AS MaxGlucose FROM Kidney)

SELECT a.Age, b.MaxGlucose
FROM Kidney a
-- Join the CTE on blood glucose equal to max blood glucose
JOIN BloodGlucoseRandom b
on a.BloodGlucoseRandom=b.MaxGlucose

Find the patient with the highest bloodpressure:

- Create the CTE
WITH BloodPressure(MaxBloodPressure)
AS (SELECT MAX(BloodPressure) FROM kidney AS MaxBloodPressure)

SELECT *
FROM Kidney a
-- Join the CTE  
Join BloodPressure b
on a.BloodPressure=b.MaxBloodPressure

you can create a window for the entire table. To create partitions using a specific column, you need to use OVER() along with PARTITION BY.

SELECT OrderID, TerritoryName, 
       -- Total price for each partition
       sum(OrderPrice)
       -- Create the window and partitions
       over(partition by TerritoryName) AS TotalPrice
FROM Orders

you want to figure out the first OrderDate in each territory or the last one. How would you do that? You can use the window functions FIRST_VALUE() and LAST_VALUE(), respectively! Here are the steps:

First, create partitions for each territory
Then, order by OrderDate
Finally, use the FIRST_VALUE() and/or LAST_VALUE() functions as per your requirement
SELECT TerritoryName, OrderDate, 
       -- Select the first value in each partition
       first_value(OrderDate) 
       -- Create the partitions and arrange the rows
       OVER(PARTITION BY TerritoryName order BY OrderDate) AS FirstOrder
FROM Orders

Use lead() next, lag() previous

SELECT TerritoryName, OrderDate, 
       -- Specify the previous OrderDate in the window
       lag(OrderDate) 
       -- Over the window, partition by territory & order by order date
       Over(partition BY TerritoryName order BY OrderDate) AS PreviousOrder,
       -- Specify the next OrderDate in the window
       lead(OrderDate) 
       -- Create the partitions and arrange the rows
       Over(partition BY TerritoryName order BY OrderDate)  AS NextOrder
FROM Orders

create a running total:

SELECT TerritoryName, OrderDate, 
       -- Create a running total
       sum(orderprice) 
       -- Create the partitions and arrange the rows
       over(partition by TerritoryName order by OrderDate) AS TerritoryTotal      
FROM Orders

Use row_number() to count the rows in different groups

SELECT TerritoryName, OrderDate, 
       -- Assign a row number
       row_number()
       -- Create the partitions and arrange the rows
       OVER(PARTITION BY TerritoryName ORDER BY OrderDate) AS OrderCount
FROM Orders

Use standered deiviation : stdev()

There is no functions to calculate the mode, so we have to create CTE() to them

-- Create a CTE Called ModePrice which contains two columns
with ModePrice (OrderPrice, UnitPriceFrequency)
AS
(
    SELECT OrderPrice, 
    ROW_NUMBER() 
    OVER(PARTITION BY OrderPrice ORDER BY OrderPrice) AS UnitPriceFrequency
    FROM Orders 
)

-- Select everything from the CTE
SELECT * FROM ModePrice

the whole version of how to use CTE to calculate mode:

WITH ModePrice (OrderPrice, UnitPriceFrequency)
AS
(
    SELECT OrderPrice,
    ROW_NUMBER() 
    OVER (PARTITION BY OrderPrice ORDER BY OrderPrice) AS UnitPriceFrequency
    FROM Orders
)

-- Select the order price from the CTE
SELECT OrderPrice AS ModeOrderPrice
FROM ModePrice
-- Select the maximum UnitPriceFrequency from the CTE
WHERE UnitPriceFrequency IN (select max(UnitPriceFrequency) FROM ModePrice)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容