Select rows with different values on different columns - sql

I'm new to SQL so this took my a long time without being able to figure it out.
My table looks like this:
+------+------+------+
|ID |2016 | 2017 |
+------+------+------+
|1 |A |A |
+------+------+------+
|2 |A |B |
+------+------+------+
|3 |B |B |
+------+------+------+
|4 |B |C |
+------+------+------+
I would like to have only the rows which have changed from 2016 to 2017:
+------+------+------+
|ID |2016 | 2017 |
+------+------+------+
|2 |A |B |
+------+------+------+
|4 |B |C |
+------+------+------+
Could you please help ?

select * from mytable where column_2016<>column_2017
assuming your column labels are column_2016 and column_2017

Related

BigQuery - How can I find the closest row to any other given row within the same table?

I have a table which looks like this:
-----------------------------------
|location|address|latitude|longitude|
-----------------------------------
|1 |a |20 |21 |
|1 |b |21 |22 |
|1 |c |23 |24 |
|2 |d |45 |50 |
|2 |e |46 |47 |
|2 |f |40 |45 |
-----------------------------------
I am trying to find which row is the closest (distance wise) to any given row of the table (for each location group) and to return this distance as a new column:
Expected output
--------------------------------------------
|location|address|latitude|longitude|distance|
--------------------------------------------
|1 |a |20 |21 |1.41 | <- Closest neighbour is b
|1 |b |21 |22 |1.41 | <- Closest neighbour is a
|1 |c |23 |24 |2.82 | <- Closest neighbour is b
|2 |d |45 |50 |1.41 | <- Closest neighbour is e
|2 |e |46 |51 |1.41 | <- Closest neighbour is d
|2 |f |41 |46 |2.82 | <- Closest neighbour is d
--------------------------------------------
In the expected output example I've calculated the Euclidean distance but I need the Haversine distance (using ST_DISTANCE in bigquery) it's just that the Euclidean is easier to calculate by hand.
My table is a sample of the actual data and contains ~500k rows. I can do a full outer join with this sample table but the full table has ~30m rows so this approach is not feasible.

transform table with duplicate

I'm trying to transform a base with duplicates into a new base according to the attached model
impossible without duplicate
I don't see how I can do
in advance thank you for your help
original base
IDu| ID | Information
1 |A |1
2 |A |2
3 |A |3
4 |A |4
5 |A |5
6 |B |1
7 |B |2
8 |B |3
9 |B |4
10 |C |1
11 |D |1
12 |D |2
13 |D |3
base to reach
ID | Resultat/table2 | plus grand valeur
A |(1,2,3,4,5) |5
B |(1,2,3,4) |4
C |(1) |1
D |(1,2,3) |3
You can use GROUP_CONCAT
(https://www.w3resource.com/mysql/aggregate-functions-and-grouping/aggregate-functions-and-grouping-group_concat.php):
SELECT
ID, GROUP_CONCAT(INFORMATION), COUNT(INFORMATION)
FROM
TABLE
GROUP BY
ID
a huge thank you.
Quick and perfect response
on the other hand how I can filter to have the greatest value
this query ranges from smallest to largest, but how to keep only the largest value
D | Resultat/table2 | greatest value
A |(1,2,3,4,5) |5
B |(1,2,3,4) |4
C |(1) |1
D |(1,2,3) |3
I tried, but without success
SELECT ID,GROUP_CONCAT(ID1)
from tournee_reduite
GROUP BY ID
ORDER BY MAX(ID1) desc;
another huge thank you

how to merge specific cells table data in oracle

I want to condionally concatenate text cells in oracle table according to sequence (SEQ) number attribute. Is it possible to do it? I need your help with the query.
For example I have the following table DATA:
|-----------------|
|ID|CODE|SEQ|TEXT |
|--|----|---|-----|
|1 |a |1 |text1|
|1 |a |2 |text2|
|2 |b |1 |text3|
|3 |c |1 |text4|
|4 |d |1 |text6|
|4 |d |2 |text7|
|4 |d |3 |text8|
-------------------
What I want to do is to create a new table DATA1 which concatenates TEXT values having the same id and code with concatenated texts in case SEQ > 1. The new table should look like this:
|-------------------------|
|ID|CODE|TEXT |
|--|----|-----------------|
|1 |a |text1 text2 |
|2 |b |text3 |
|3 |c |text4 |
|4 |d |text6 text7 text8|
---------------------------
listagg() function might be used with grouping by id and code.
select id, code,
listagg(text,' ') within group (order by seq) as text
from tab
group by id, code
Demo

Pivoting Dates to Day of week

I'm currently trying to create a grid showing worked hours of employees.
Here's what my data look like (simplified) :
|ID |Client |Task |Hours |Date |
------------------------------------------
|1 |ABC |A |3 |09/06/2014|
|2 |ABC |A |5 |09/06/2014|
|3 |DEF |B |8 |10/06/2014|
|4 |DEF |C |8 |11/06/2014|
|5 |ABC |A |8 |12/06/2014|
And here's what the output must look like:
|Client |Task |Sun |Mon |Tue |Wed |Thu |Fri |Sat |
--------------------------------------------------
|ABC |A | |3 | | |8 | | |
|ABC |A | |5 | | | | | |
|DEF |B | | |8 | | | | |
|DEF |C | | | |8 | | | |
My problem is really close to this one. However there's a major diffrence: it's possible in my case to have multiple values for the same combination of Client-Task-Date.
As shown in the desired output, employees will sometime seperate their work hours even if they worked for the same client and on the same task and i can't use aggregate since all the data shown in the grid will be interactive to the end user.
Is there a way to obtain such output using pivot or any other SQL mechanics such as CASE WHEN ?
WITH t AS (
SELECT
Client,
Task,
Hours,
ROW_NUMBER() OVER(PARTITION BY Client,Task,Date ORDER BY Date) rn,
DATEPART(dw,date) DayOfWeek
FROM MyTable
)
SELECT Client, Task, [1] Sun, [2] Mon, [3] Tues, [4] Wed, [5] Thu, [6] Fri, [7] Sat
FROM t
PIVOT(SUM(Hours) FOR DayOfWeek IN ([1],[2],[3],[4],[5],[6],[7])) p

SQL: triple-nested many to many query

I'm trying to fix my nested query, I have these tables:
cdu_groups_blocks
------------------------
|id |group_id |block_id|
------------------------
|1 |1 |1 |
|2 |1 |2 |
|3 |1 |3 |
------------------------
cdu_blocks: cdu_blocks_sessions:
-------------------------- ---------------------------
|id |name |enabled | |id |block_id |session_id |
-------------------------- ---------------------------
|1 |block_1 |1 | |1 |1 |1 |
|2 |block_2 |1 | |2 |1 |2 |
|3 |block_3 |1 | |3 |2 |3 |
-------------------------- |4 |2 |4 |
|5 |3 |5 |
|6 |3 |6 |
---------------------------
cdu_sessions: cdu_sessions_lessons
-------------------------- ----------------------------
|id |name |enabled | |id |session_id |lesson_id |
-------------------------- ----------------------------
|1 |session_1 |1 | |1 |1 |1 |
|2 |session_2 |1 | |2 |1 |2 |
|3 |session_3 |1 | |3 |2 |3 |
|4 |session_4 |0 | |4 |4 |4 |
|5 |session_5 |1 | |5 |4 |5 |
|6 |session_6 |0 | |6 |5 |6 |
-------------------------- ----------------------------
cdu_lessons:
--------------------------
|id |name |enabled |
--------------------------
|1 |lesson_1 |1 |
|2 |lesson_2 |1 |
|3 |lesson_3 |1 |
|4 |lesson_4 |1 |
|5 |lesson_5 |0 |
|6 |lesson_6 |0 |
--------------------------
It's a many-to-many which links to another many-to-many which links to another many-to-many.
Essentially I want to get all lesson_id(s) associated with a particular group_id.
So far I have this, but it's throwing up various SQL errors:
SELECT b.* FROM
(
SELECT block_id, group_id FROM cdu_groups_blocks
JOIN cdu_blocks ON cdu_blocks.id = cdu_groups_blocks.block_id
WHERE group_id = $group_id
AND enabled = 1
) AS b
INNER JOIN
(
SELECT l.* FROM
(
SELECT session_id, block_id FROM cdu_blocks_sessions
JOIN cdu_sessions ON cdu_sessions.id = cdu_blocks_sessions.session_id
AND enabled = 1
) AS s
INNER JOIN
(
SELECT lesson_id, session_id FROM cdu_sessions_lessons
JOIN cdu_lessons ON cdu_lessons.id = cdu_sessions_lessons.lesson_id
WHERE enabled = 1
) AS l
WHERE s.session_id = l.session_id
) AS sl
WHERE sl.block_id = g.block_id
Any help would be much appreciated!
sl.block_id is from s table in your first select inside sl subselect.
Just get it. Change:
SELECT l.* FROM ...
to
SELECT l.*, s.block_id FROM ...