瀏覽標籤:

SQL

[MySQL][LeetCode][Easy] 196. Delete Duplicate Emails

心得

題目要求刪除同樣Email的資料,在DELETE的條件WHERE裡面不能包含異動的表(Person),所以這裡再包了一層SELECT來排除編譯錯誤的問題,而這層必須給予別名(強制)否則會編譯錯誤。

問題

Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id.

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | [email protected] |
| 2  | [email protected]  |
| 3  | [email protected] |
+----+------------------+
Id is the primary key column for this table.

For example, after running your query, the above Person table should have the following rows:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | [email protected] |
| 2  | [email protected]  |
+----+------------------+

答案

DELETE 
FROM    Person
WHERE   Id 
NOT IN (SELECT y.*
        FROM (  SELECT MIN(z.Id)
                FROM Person AS z
                GROUP BY z.Email) AS y)

 

       

[MySQL][LeetCode][Easy] 197. Rising Temperature

心得

題目要求找出溫度比前一天高的資料,這裡用了DATE_SUBTO_DAYS兩種方式來解答。

題目

Given a Weather table, write a SQL query to find all dates’ Ids with higher temperature compared to its previous (yesterday’s) dates.

+---------+------------+------------------+
| Id(INT) | Date(DATE) | Temperature(INT) |
+---------+------------+------------------+
|       1 | 2015-01-01 |               10 |
|       2 | 2015-01-02 |               25 |
|       3 | 2015-01-03 |               20 |
|       4 | 2015-01-04 |               30 |
+---------+------------+------------------+

For example, return the following Ids for the above Weather table:

+----+
| Id |
+----+
|  2 |
|  4 |
+----+

答案

  1. Sub Query
    # Write your MySQL query statement below
    SELECT  a.Id
    FROM    Weather AS a
    WHERE   (   SELECT  z.Temperature
                FROM    Weather AS z
                WHERE   DATE_SUB(a.Date, INTERVAL 1 DAY) = z.Date) < a.Temperature
  2. Join
    # Write your MySQL query statement below
    SELECT  a.Id
    FROM    Weather AS a
    JOIN    Weather AS b
    ON      DATE_SUB(a.Date, INTERVAL 1 DAY) = b.Date
    WHERE   a.Temperature > b.Temperature
  3. TO_DAYS
    # Write your MySQL query statement below
    SELECT  a.Id
    FROM    Weather AS a
    JOIN    Weather AS b
    ON      TO_DAYS(a.Date) - TO_DAYS(b.Date) = 1
    WHERE   a.Temperature > b.Temperature

     

參考:

  1. DATE_ADD() 與 DATE_SUB() 日期的加法與減法
  2. Mysql日期和時間函數不求人
       

[MySQL][LeetCode][Easy] 183. Customers Who Never Order

心得

這題要show出沒有訂過東西的客戶,所以可以使用LEFT JOIN來關聯兩張表。

問題

Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything.

Table: Customers.

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Table: Orders.

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

Using the above tables as example, return the following:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

答案

  1. LEFT JOIN
    # Write your MySQL query statement below
    SELECT      a.Name AS Customers
    FROM        Customers AS a
    LEFT JOIN   Orders AS b
    ON          a.Id = b.CustomerId
    WHERE       b.CustomerId IS NULL
  2. Sub Query
    # Write your MySQL query statement below
    SELECT  a.Name AS Customers
    FROM    Customers AS a
    WHERE   (   SELECT  COUNT(1)
                FROM    Orders AS z
                WHERE   z.CustomerId = a.Id) = 0
       

[MySQL][LeetCode][Easy] 176. Second Highest Salary

心得:

找出該資料表內第二高薪水的筆數,若無則回傳null。

問題:

Write a SQL query to get the second highest salary from the Employee table.

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

For example, given the above Employee table, the second highest salary is 200. If there is no second highest salary, then the query should return null.

答案:

  1. Sub Query
    # Write your MySQL query statement below
    SELECT  MAX(a.Salary) AS SecondHighestSalary
    FROM    Employee AS a
    WHERE   a.Salary < (SELECT  MAX(z.Salary)
                        FROM    Employee AS z)
  2. DISTINCT > 不重複
    # Write your MySQL query statement below
    SELECT
    (
        SELECT DISTINCT Salary
        FROM            Employee
        ORDER BY        Salary DESC
        LIMIT           1, 1
    ) AS SecondHighestSalary
  3. GROUP BY > 不重複
    # Write your MySQL query statement below
    SELECT
    (
        SELECT          Salary
        FROM            Employee
        GROUP BY        Salary
        ORDER BY        Salary DESC
        LIMIT           1, 1
    ) AS SecondHighestSalary

     

       

[MySQL][LeetCode][Easy] 181. Employees Earning More Than Their Managers

心得:

題目要求找出有哪些人的薪水比主管高,找出名字並修改欄位名稱為Employee

題目:

The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id.

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager.

+----------+
| Employee |
+----------+
| Joe      |
+----------+

答案:

  1. Sub Select
    # Write your MySQL query statement below
    SELECT  a.Name AS Employee
    FROM    Employee AS a
    WHERE   a.Salary > (SELECT  z.Salary 
                        FROM    Employee AS z
                        WHERE   z.Id = a.ManagerId);
  2. Join
    # Write your MySQL query statement below
    SELECT  a.Name AS Employee
    FROM    Employee AS a
    JOIN    Employee AS b
    ON      a.ManagerId = b.Id
    WHERE   a.Salary > b.Salary
  3. From
    # Write your MySQL query statement below
    SELECT  a.Name AS Employee
    FROM    Employee AS a, Employee AS b
    WHERE   a.ManagerId = b.Id
    AND     a.Salary > b.Salary

     

       

[MySQL][LeetCode][Easy] 175. Combine Two Tables

心得:

題目要求找出Person表內所有人員的地址,就算是空的也無所謂,所以不用理會Address表內是否有Person表的資料,這題必須使用LEFT JOIN來關聯。

問題:

Table: Person

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId is the primary key column for this table.

Table: Address

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId is the primary key column for this table.

Write a SQL query for a report that provides the following information for
each person in the Person table, regardless if there is an address for each
of those people:

FirstName, LastName, City, State

答案:

# Write your MySQL query statement below
SELECT      a.FirstName, a.LastName, b.City, b.State
FROM        Person AS a
LEFT JOIN   Address AS b
ON          a.PersonId = b.PersonId

參考:

  1. [SQL] 一張圖片解釋 JOIN
       

[MSSQL] 當自動識別欄位需要Insert資料時應該怎麼辦 ?

今天在手動將MySQL資料匯入MSSQL時遇到了這個問題,但又不想將自動識別欄位取消掉,於是乎找了一下資料來解決 …

 

語法:

SET IDENTITY_INSERT TABLE_NAME OFF;
SET IDENTITY_INSERT TABLE_NAME ON;

 

範例:

SET IDENTITY_INSERT [dbo].[Demo] ON;

INSERT INTO [dbo].[Demo] ([ID], [Name]) VALUES (N'1', N'王小名');

INSERT INTO [dbo].[Demo] ([ID], [Name]) VALUES (N'2', N'王大名');

SET IDENTITY_INSERT [dbo].[Demo] OFF;

 

 

參考:

  1. 在程式開發時使用SET IDENTITY_INSERT似乎無效?
  2. SQL錯誤訊息:當IDENTITY_INSERT 設為OFF 時,無法將外顯
       

[MSSQL] 使用 T-SQL 實作分頁

很多表格會遇上資料有上萬筆資料或者上千萬時的大數據,這時如果還是把所有資料撈出來在分頁的話,會造成使用者頁面讀取時間過久,更會有伺服器壓力倍增的問題,這裡提供一個SQL解決方案。

SQL如下:

DECLARE @PageNum AS BIGINT;
DECLARE @PageSize AS BIGINT;
DECLARE @PageCount AS BIGINT;
SET @PageNum = 3;
SET @PageSize = 10;
SET @PageCount = (	SELECT	COUNT(1)
					FROM	dbo.TBase_Product
					WHERE	Product_State != 9) / @PageSize;

IF @PageNum < 1	SET @PageNum = 1;

WITH Temp AS
(
	SELECT	*,
			ROW_NUMBER() OVER(ORDER BY Product_ID) AS RowNum
	FROM dbo.TBase_Product
)

SELECT	RowNum, @PageCount AS PageCount
FROM	Temp
WHERE	RowNum 
		BETWEEN ((@PageNum - 1) * @PageSize + 1) 
			AND (@PageNum * @PageSize)
ORDER BY Product_ID;

執行結果:

2016-09-03 01_01_10-SQLQuery9.sql - exfast.me,6000.iPCE_Coding (shuangrain (143))_ - Microsoft SQL S

 

 

參考:

  1. How to return a page of results from SQL?
  2. Select Count(*) / Count(1) / Count(欄位名) 的差異