I have to write an SQL query for the following:
Input:
Id | Name
-- | ----
1 | A
2 | B
3 | C
Output:
Id | Name | IdType
-- | ---- | -----
1 | A | O
2 | B | E
3 | C | O
I can extract odd or even rows by putting where condition Id % 2 = 0. But I'm not sure how to put 'O' or 'E' in the new column.
Like this, using the IF() function:
SELECT Id, Name, IF(Id % 2 = 0, 'E', 'O') AS IdType FROM table_name;
You make use of CASE and print E when Id%2=0 and O if Id%2 is not equal to 0
SELECT Id,Name,
CASE WHEN (Id%2)=0 THEN 'E'
ELSE 'O' END AS IdType
FROM [YourTable]
Use this query If you want to update your table
UPDATE table_name SET IdType = CASE
WHEN mod (Id, 2) = 0 THEN 'E'
WHEN mod (Id, 2) <> 0 THEN 'O'
ELSE IdType
END
If you just want to print,then Robby Cornelissen had a perfect answer for you
Related
Sorry for my lack of knowledge in MySQL but how do you get the same value in different field?
For example if i have a table like so :
+-----+-----+-----+
| id | A | B |
+=====+=====+=====+
| 1 | 1 | 2 |
| 2 | 3 | 1 |
+-----+-----+-----+
And i would like to get the value 1 from A and B.
I tried doing something like :
SELECT A, B FROM table_name WHERE A = 1 AND B = 1
But this won't return a value if somehow A or B doesn't have the value 1. In cases like that I want it to only return the value 1 from the column that does have it. I want something like this :
SELECT A, B FROM table_name WHERE value = 1
I think you want OR:
SELECT A, B
FROM t
WHERE A = 1 OR B = 1
This can be shortened using IN:
WHERE 1 IN (A, B)
You should use query as:
SELECT A, B FROM table_name WHERE A = 1 OR B = 1
Here, you get rows which have either A=1 or B=1 or both A & B = 1.
If I have a table like this:
id column1 column2
1 A A
1 B B
1 C A
2 B A
2 B C
2 C C
3 D C
3 B D
3 E D
what I want is counting distinct ids which don't contain column1=A or column2=A.
From my table, count(distinct(id)) should be 1 because id 1 has a rows contain column1=A, column2=A and id 2 , column2=A. so id 3 is the only id which rows don't contain column1 != A or column2 != A.
Which query should I use?
This might help you;)
SQL Fiddle
MySQL 5.6 Schema:
CREATE TABLE SO_TEST (
id int,
column1 char(2),
column2 char(2)
);
INSERT SO_TEST VALUES
(1,'A','A'),
(1,'B','B'),
(1,'C','A'),
(2,'B','A'),
(2,'B','C'),
(2,'C','C'),
(3,'D','C'),
(3,'B','D'),
(3,'E','D');
Query 1:
SELECT COUNT(1) AS RESULT
FROM (
SELECT id, GROUP_CONCAT(CONCAT(CONCAT(column1,','),column2)) STR FROM SO_TEST GROUP BY id
) TMP
WHERE FIND_IN_SET('A',TMP.STR) = 0
Okay, let's explain it.
In subquery, I've retrieved all column1, column2 value by group id and concat them, and it will return us follow results and you can try it in sqlfiddle.
+----+-------------+
| id | STR |
+----+-------------+
| 1 | A,A,B,B,C,A |
| 2 | B,A,B,C,C,C |
| 3 | D,C,B,D,E,D |
+----+-------------+
So In main query, I used FIND_IN_SET(param1, param2) in WHERE clause, this function will return us the index of param1 in param2(param2's every element must be separated by a comma), and if param1 not in param2, return 0, so we could be clear about WHERE clause.
At last count(1) will help us get what we want.
Results:
| RESULT |
|--------|
| 1 |
From what I understand here is distinct IDs
select count(distinct id) from test2
where col1 !='A' AND col2 !='A'
OUTPUT
+-------------------+
| COUNT(DISTINCTID) |
+-------------------+
| 3 |
+-------------------+
You can do something like this, that will return you the count of rows grouped by ID when column1 is distinc to 'A' and column2 is distinct to 'B':
SELECT COUNT(*) as cont
FROM test
WHERE column1 != 'A' AND column2 != 'A'
GROUP BY id
In your example that will return you:
id cont
1 1
2 2
3 3
Because id 1 has only (B, B) as a good value, id 2 has (B, C) and (C, C) and id 3 has all as a good value.
Hope it will help you.
Here's an example Table layout:
TABLE_A: TABLE_B: TABLE_A_B:
id | a | b | c id | name a_id | b_id
--------------------- --------- -----------
1 | true | X | A 1 | A 1 | 1
2 | true | Z | null 2 | B 1 | 2
3 | false | X | null 3 | C 2 | 2
4 | true | Y | Q 4 | 1
5 | false | null | null 4 | 2
5 | 1
Possible Values:
TABLE_A.a: true, false
TABLE_A.b: X, Y, Z
TABLE_A.c: A, B, C, ... basically arbitrary
TABLE_B.name: A, B, C, ... basically arbitrary
What I want to achieve:
SELECT all rows from TABLE_A
SUM(where a = true),
SUM(where a = false),
SUM(where b = 'X'),
SUM(where b = 'Y'),
SUM(where b = 'Z'),
SUM(where b IS NULL),
and also get the SUMs for all distinct TABLE_A.c values.
and also get the SUMs for all those TABLE_A_B relations.
The result for the example Table above should look like:
aTrue | aFalse | bX | bY | bZ | bNull | cA | cQ | cNull | nameA | nameB | nameC
-------------------------------------------------------------------------------
3 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 3 | 3 | 3 | 0
What I've done so far:
SELECT
SUM(CASE WHEN a = true THEN 1 ELSE 0 END) AS aTrue,
SUM(CASE WHEN b = false THEN 1 ELSE 0 END) AS aFalse,
SUM(CASE WHEN b = 'X' THEN 1 ELSE 0 END) AS bX,
...
FROM TABLE_A
What's my problem?
Selecting column TABLE_A.a and TABLE_A.b is easy, because there's a fixed number of possible values.
But I can't figure out how to count the distinct values of TABLE_A.c. And basically the same problem for the JOINed TABLE_B, because the number of values within TABLE_B is unknown and can change over time.
Thanks for your help! :)
EDIT1: New (preferred) SQL result structure:
column | value | sum
----------------------------
TABLE_A.a | true | 3
TABLE_A.a | false | 2
TABLE_A.b | X | 2
TABLE_A.b | Y | 1
TABLE_A.b | Z | 1
TABLE_A.b | null | 1
TABLE_A.c | A | 1
TABLE_A.c | Q | 1
TABLE_A.c | null | 3
TABLE_B.name | A | 3
TABLE_B.name | B | 3
TABLE_B.name | C | 0
From your original request of rows as a simulated pivot. By doing a SUM( logical condition ) basically returns 1 if true, 0 if false. So, since the column "a" is true or false, simple sum of "a" or NOT "a" (for the false counts -- NOT FALSE = TRUE). Similarly, your "b" column, so b='X' = true counted as 1, else 0.
In other sql engines, you might see it as SUM( case/when ).
Now, since your table counts don't rely on each other, they can be separate SUM() into their own sub-alias query references (pqA and pqB for pre-queryA and pre-queryB respectively). Since no group by, they will each result in a single row. With no join will create a Cartesian, but since 1:1 ratio, will only return a single record of all columns you want.
SELECT
pqA.*, pqB.*
from
( SELECT
SUM( ta.a ) aTrue,
SUM( NOT ta.a ) aFalse,
SUM( ta.b = 'X' ) bX,
SUM( ta.b = 'Y' ) bY,
SUM( ta.b = 'Z' ) bZ,
SUM( ta.b is null ) bNULL,
SUM( ta.c = 'A' ) cA,
SUM( ta.c = 'Q' ) cQ,
SUM( ta.c is null ) cNULL,
COUNT( distinct ta.c ) DistC
from
table_a ta ) pqA,
( SELECT
SUM( b.Name = 'A' ) nameA,
SUM( b.Name = 'B' ) nameB,
SUM( b.Name = 'C' ) nameC
from
table_a_b t_ab
join table_b b
ON t_ab.b_id = b.id ) pqB
This option gives your second (preferred) output
SELECT
MAX( 'TABLE_A.a ' ) as Basis,
CASE when a then 'true' else 'false' end Value,
COUNT(*) finalCnt
from
TABLE_A
group by
a
UNION ALL
SELECT
MAX( 'TABLE_A.b ' ) as Basis,
b Value,
COUNT(*) finalCnt
from
TABLE_A
group by
b
UNION ALL
SELECT
MAX( 'TABLE_A.c ' ) as Basis,
c Value,
COUNT(*) finalCnt
from
TABLE_A
group by
c
UNION ALL
SELECT
MAX( 'TABLE_B.name ' ) as Basis,
b.Name Value,
COUNT(*) finalCnt
from
table_a_b t_ab
join table_b b
ON t_ab.b_id = b.id
group by
b.Name
I think You will need to build dynamic query as you don't know possible values for column C in table A. So you can write store procedure where you can get list of distinct value for Column C in one variable and by using "Do WHILE" you can construct your dynamic query.
Please let me know if you need more help in detail
Dynamic SQL
I'm trying to display the column name of the my table if it has the value 1
| A | B | C | D |
| 0 | 1 | 1 | 0 |
In this case i would like to get the result:
| Column |
| B |
| C |
I wrote the following query but it is not working:
SHOW COLUMNS
FROM `questions`
WHERE VALUES=`1`
If you just need a list of the columns that contain the value = 1, you should be able to use the following query:
select col
from
(
select col,
case s.col
when 'A' then A
when 'B' then B
when 'C' then C
when 'D' then D
end AS val
from yourtable
cross join
(
select 'A' AS col union all
select 'B' union all
select 'C' union all
select 'D'
) s
) s
where val = 1;
See SQL Fiddle with Demo. This uses a virtual table with your column names (A, B, etc) to unpivot your columns and then you just return only the column names that contain a value of 1. Credit for this technique goes to #Andriy M.
I have this table [Table 1]
cid | arrived | date_arrived
The [arrived field can have a value of [T] or [F], the value is [F] the date arrived field is NULL
1 records may appear only up to maximum of 2 (1 record for arrived=T and another record for arrived=F) But there are also records that may appear only once
1 | T | 2012-02-01
2 | F | [Null]
1 | F | [Null]
3 | T | 2012-03-05
I need a query that will show something like this
cid | arrived | not_arrived
1 Yes Yes
2 No Yes
3 Yes No
This works:
SELECT
cid,
SUM(arrived = 'T') > 0 as arrived,
SUM(arrived = 'F') > 0 as not_arrived
FROM [Table 1]
GROUP BY cid;
You can try it here: http://sqlfiddle.com/#!2/2b5a7/1/0
try
select cid,
case when find_in_set('T', group_concat(arrived)) > 0 then 'yes' else 'no' end as arrived,
case when find_in_set('F', group_concat(arrived)) > 0 then 'yes' else 'no' end as not_arrived
from table1
group by cid