How do i show values from the table - mysql

how do i show all values from this table
+------+---------+-------+--------+-----+
| A | B | C | D | E |
+------+---------+-------+--------+-----+
| 2 | K | M | NULL | S |
| 3 | L | C | NULL | N |
| 4 | R | P | NULL | N |
| 5 | P | N | C | N |
| 6 | Y | Q | NULL | S |
| 7 | S | T | NULL | S |
| 8 | C | M | NULL | N |
| 9 | X | C | NULL | S |
| 10 | E | Q | NULL | N |
| 11 | A | C | NULL | S |
| 12 | C | NULL | C | N |
| 13 | F | Q | NULL | N |
| 14 | L | NULL | C | S |
| 15 | S | P | NULL | S |
+------+---------+-------+--------+-----+
to this.
show the first 8 values from column A, B and the 7 will be 5 in column A
SELECT A, B FROM letters LIMIT 8;
+------+--------+
| A | B |
+------+--------+
| 2 | K |
| 3 | L |
| 4 | R |
| 5 | P |
| 6 | Y |
| 5 | S |
| 8 | C |
| 9 | X |
+------+--------+

You'll want to use a case expression or the if() function. My preference is a case expression because it's more portable. Furthermore you'll need to supply an ORDER BY clause since records in a table have no ordering.
SELECT CASE WHEN A=7 THEN 5 ELSE A END as A, B FROM letters ORDER BY letters.A LIMIT 8;

Related

MySQL - calculate percent of a column with multiple column grouping

I have a table
desc test;
+--------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id | int(100) | YES | | NULL | |
| name | varchar(100) | YES | | NULL | |
| dept | varchar(10) | YES | | NULL | |
| sub | varchar(10) | YES | | NULL | |
| salary | int(100) | YES | | NULL | |
+--------+--------------+------+-----+---------+-------+
select * from test;
+------+-----------+------+------+--------+
| id | name | dept | sub | salary |
+------+-----------+------+------+--------+
| 1 | Rishabh | A | X | 150 |
| 2 | Manish | B | Y | 120 |
| 3 | Sachin | A | Z | 160 |
| 4 | Abhiskhek | C | Z | 100 |
| 5 | Manan | B | Z | 170 |
| 6 | Rahul | C | X | 150 |
| 7 | Rohan | C | Y | 120 |
| 8 | Mukul | B | Z | 110 |
| 9 | Lalit | B | X | 130 |
+------+-----------+------+------+--------+
So far I am able to do percent of a single column group
select dept, sum(salary), round(sum(salary)*100/t.s,2) as `perc`
from test cross join (select sum(salary) as s from test) t group by dept;
which yields the following:
+------+-------------+-------+
| dept | sum(salary) | perc |
+------+-------------+-------+
| A | 310 | 25.62 |
| B | 530 | 43.80 |
| C | 370 | 30.58 |
+------+-------------+-------+
so now I have another column to group by, I made the query,
select dept, sub, sum(salary), round(sum(salary)*100/t.s) as `perc`
from test cross join (select sum(salary) as s from test) t group by dept,sub;
which output the following:
+------+------+-------------+-------+
| dept | sub | sum(salary) | perc |
+------+------+-------------+-------+
| A | X | 150 | 12.40 |
| A | Z | 160 | 13.22 |
| B | X | 130 | 10.74 |
| B | Y | 120 | 9.92 |
| B | Z | 280 | 23.14 |
| C | X | 150 | 12.40 |
| C | Y | 120 | 9.92 |
| C | Z | 100 | 8.26 |
+------+------+-------------+-------+
it is making the relevant row percentage from the total sum = select sum(salary) from test;
but I expect it to show percent from it's respective group only, (in this case percent of sub's salary from total dept salary)
Expected output:
+------+------+-------------+-------+
| dept | sub | sum(salary) | perc |
+------+------+-------------+-------+
| A | X | 150 | 48.39 |
| A | Z | 160 | 51.61 |
| B | X | 130 | 24.53 |
| B | Y | 120 | 22.64 |
| B | Z | 280 | 52.83 |
| C | X | 150 | 40.54 |
| C | Y | 120 | 32.43 |
| C | Z | 100 | 27.03 |
+------+------+-------------+-------+
[yes I calculated these manually]
Kindly help me with correcting my query.

mysql query for adding non existing rows with count zero

"Table A" & "Table B" are my initial tables for the query. Result is the final table as shown in the following figure.Find Non-existing rows
Table A:
| Date | Name | Count |
|:----------:|:----:|:-----:|
| 01-01-2020 | A | 5 |
| 01-01-2020 | B | 15 |
| 02-01-2020 | B | 20 |
| 02-01-2020 | C | 15 |
| 02-01-2020 | D | 30 |
| 03-01-2020 | A | 30 |
| 03-01-2020 | D | 10 |
Table B:
| Name |
|:----:|
| A |
| B |
| C |
| D |
Result:
| Date | Name | Count |
|:----------:|:----:|:-----:|
| 01-01-2020 | A | 5 |
| 01-01-2020 | B | 15 |
| 01-01-2020 | C | 0 |
| 01-01-2020 | D | 0 |
| 02-01-2020 | A | 0 |
| 02-01-2020 | B | 20 |
| 02-01-2020 | C | 15 |
| 02-01-2020 | D | 30 |
| 03-01-2020 | A | 30 |
| 03-01-2020 | B | 0 |
| 03-01-2020 | C | 0 |
| 03-01-2020 | D | 10 |
cross join distinct dates from a to distinct id from b then left join a
drop table if exists t,t1;
create table t
(id varchar(1),dt date);
create table t1
(id varchar(1));
insert into t values
('a','2019-01-01'),('b','2019-01-01'),
('b','2019-02-01'),('d','2019-01-01'),
('c','2019-03-01');
insert into t1 values
('a'),('b'),('c'),('d');
select t3.id,t3.dt,t.id,t.dt
from
(
select distinct dt,s.id from t
cross join
(select distinct id from t1) s
) t3
left join t on t.id = t3.id and t.dt =t3.dt
order by t3.dt,t3.id;
+------+------------+------+------------+
| id | dt | id | dt |
+------+------------+------+------------+
| a | 2019-01-01 | a | 2019-01-01 |
| b | 2019-01-01 | b | 2019-01-01 |
| c | 2019-01-01 | NULL | NULL |
| d | 2019-01-01 | d | 2019-01-01 |
| a | 2019-02-01 | NULL | NULL |
| b | 2019-02-01 | b | 2019-02-01 |
| c | 2019-02-01 | NULL | NULL |
| d | 2019-02-01 | NULL | NULL |
| a | 2019-03-01 | NULL | NULL |
| b | 2019-03-01 | NULL | NULL |
| c | 2019-03-01 | c | 2019-03-01 |
| d | 2019-03-01 | NULL | NULL |
+------+------------+------+------------+
12 rows in set (0.05 sec)
PS - if you want solutions which are close to your model you should include table definitions and sample data as text in the question (which we can use) rather than links to images (which cannot use)

How can I merge multiple rows with same ID into one row?

How can I merge multiple rows with same ID into one row.
I have table:
+----+------+------+------+
| ID | A | B | C |
+----+------+------+------+
| 1 | 123 | 31 | 456 |
| 1 | 412 | NULL | 1 |
| 2 | 567 | 38 | 4 |
| 2 | 567 | NULL | NULL |
| 3 | 2 | NULL | NULL |
| 3 | 5 | NULL | NULL |
| 4 | 6 | 1 | NULL |
| 4 | 8 | NULL | 5 |
| 4 | NULL | NULL | 5 |
+----+------+------+------+
I want to have table :
I have table:
+----+-----+------+------+-----+------+------+------+------+----+
| ID | A | B | C | A2 | B2 | C2 | A3 | B3 | C3 |
+----+-----+------+------+-----+------+------+------+------+----+
| 1 | 123 | 31 | 456 | 412 | NULL | 1 | | | |
| 2 | 567 | 38 | 4 | 567 | NULL | NULL | | | |
| 3 | 2 | NULL | NULL | 5 | NULL | NULL | | | |
| 4 | 6 | 1 | NULL | 8 | NULL | 5 | NULL | NULL | 5 |
+----+-----+------+------+-----+------+------+------+------+----+
Try This:-
1 :- Please Change data table structure to disallow null value.
Query :-
SELECT
GROUP_CONCAT(if (`A` ='0', 'NOVAL', `A`)SEPARATOR '----') as A,
GROUP_CONCAT(if (`B` ='0', 'NOVAL', `B`)SEPARATOR '----') as B,
GROUP_CONCAT(if (`C` ='0', 'NOVAL', `C`)SEPARATOR '----') as C
FROM que1
GROUP BY id
Now You can get the value using mysql_fetch_array

Recursive call in mySQL

I have some data which has three columns
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| a | 1 | p |
| a | 3 | q |
| 1 | b | r |
| 1 | c | s |
| 3 | x | t |
| b | l | u |
| b | x | v |
| c | t | w |
| c | z | m |
+------+------+------+
Column 1 entries can have more than 1 value.
Now if user searches for 1 in the table, it returns all the values corresponding to 1,
now all entries corresponding to b in column 1 should be repeated and so on.. so if user searches for 1 the output should be
+------+------+
| col1 | col2 |
+------+------+
| 1 | b |
| 1 | c |
| 3 | x |
| b | o |
| b | x |
| c | t |
| c | z |
+------+------+
Can somebody help me with the select query.?

Is there a way in SQL (MySQL) to do a "round robin" ORDER BY on a particular field?

Is there a way in SQL (MySQL) to do a "round robin" ORDER BY on a particular field?
As an example, I would like to take a table such as this one:
+-------+------+
| group | name |
+-------+------+
| 1 | A |
| 1 | B |
| 1 | C |
| 2 | D |
| 2 | E |
| 2 | F |
| 3 | G |
| 3 | H |
| 3 | I |
+-------+------+
And run a query that produces results in this order:
+-------+------+
| group | name |
+-------+------+
| 1 | A |
| 2 | D |
| 3 | G |
| 1 | B |
| 2 | E |
| 3 | H |
| 1 | C |
| 2 | F |
| 3 | I |
+-------+------+
Note that the table may have many rows, so I can't do the ordering in the application. (I'd obviously have a LIMIT clause as well in the query).
I'd try something like:
SET #counter = 0;
SELECT (#counter:=#counter+1)%3 as rr, grp, name FROM table ORDER by rr, grp
What you can do is create a temporary column in which you create sets to give you something like this:
+-------+------+-----+
| group | name | tmp |
+-------+------+-----+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 3 |
| 2 | D | 1 |
| 2 | E | 2 |
| 2 | F | 3 |
| 3 | G | 1 |
| 3 | H | 2 |
| 3 | I | 3 |
+-------+------+-----+
To learn how to create the sets, have a look at this question/answer.
Then its a simple
ORDER BY tmp, group, name
You can use MySQL variables to do this.
SELECT grp, name, #row:=#row+1 from table, (SELECT #row:=0) r ORDER BY (#row % 3);
+------+------+--------------+
| grp | name | #row:=#row+1 |
+------+------+--------------+
| 1 | A | 1 |
| 2 | D | 4 |
| 3 | G | 7 |
| 1 | B | 2 |
| 2 | E | 5 |
| 3 | H | 8 |
| 1 | C | 3 |
| 2 | F | 6 |
| 3 | I | 9 |
+------+------+--------------+