I'm try to skip values continuously in my MySQL table, for example:
I have a table here
time value
t1 val1
t2 val2
t3 val3
t4 val4
t5 val5
And the result that i need is
time value
t1 val1
t3 val3
t5 val5
Hopefully you guys understand my problem
Similarly I need to skip by 2 values,3,4 and 5.
Assuming that the order is defined by time, in MySQL 8+ you can use row_number() to assign a number to each row ordered by time and then pick only the rows with an odd number using the modulo operator %.
SELECT x.time,
x.value
FROM (SELECT t.time,
t.value,
row_number() OVER (ORDER BY t.time) rn) x
WHERE rn % 2 = 1;
You can use IN statement
SELECT * FROM TABLE_NAME WHERE NOT IN(values);
values=(2,4,....);
You will get results , and in values you can pass array as you don't want value
Related
I've data like below:
ID Task Time
1 X started T1
2 X ended T2
3 X started T3 [wrong entry in data]
4 X started T4
5 X ended T5
6 Y started T6 [wrong entry in data]
7 Y started T7
8 Y ended T8
And, I need to get the data from above in started/ended fashion, but in case of wrong entry I need to pickup the latest one [as T4>T3 and T7>T6].
How can I write SQL on above dataset to get below result ?
ID Task Time
1 X started T1
2 X ended T2
4 X started T4
5 X ended T5
7 Y started T7
8 Y ended T8
You may use the difference of two row_number()s to define unique groups for the consecutive duplicate values of Task column, then get the max of Time and ID columns, try the following:
select max(ID), Task, max(Time) Time
from
(
select *,
row_number() over (order by Time) -
row_number() over (partition by Task order by Time) grp
from table_name
) T
group by Task, grp
order by max(Time)
See a demo.
For MySQL 5.7 try the following:
set #gr=0;
set #ts=null;
select max(ID), Task, max(Time)
Time
from
(
select *,
if(#ts<>Task, #gr:=#gr+1,
#gr) grp,
#ts:=Task
from table_name
order by Time
) T
group by Task, grp
order by max(Time)
Demo.
use a subquery in the where to match the ID, the subquery returns the ID of the row that matches the task (in the primary query), if there is more than one row with the same task value, it will return the row with the greatest id value.
SELECT * FROM `mytable` p1
where id = (select id from `mytable` p2
where p2.task= p1.task
order by id DESC limit 1);
Suppose I have data containing two columns I am interested in. Ideally, the data in these is always in matching sets like this:
A 1
A 1
B 2
B 2
C 3
C 3
C 3
However, there might be bad data where the same value in one column has different values in the other column, like this:
D 4
D 5
or:
E 6
F 6
How do I isolate these bad rows, or at least show that some of them exist?
You can use exists:
select t.*
from t
where exists (select 1 from t t2 where t2.col1 = t.col1 and t2.col2 <> t.col2);
If you just want the col1 values that have non-matches, you can use aggregation:
select col1, min(col2), max(col2)
from t
group by col1
having min(col2) <> max(col2);
Using MIN and MAX as analytic functions we can try:
WITH cte AS (
SELECT t.*, MIN(col2) OVER (PARTITION BY col1) AS min_col2,
MAX(col2) OVER (PARTITION BY col1) AS max_col2
FROM yourTable t
)
SELECT col1, col2
FROM cte
WHERE min_col2 <> max_col2;
The above approach, while seemingly verbose, would return all offending rows.
exTab
PK col1 col2 col3
---------------------------------
1 val1 val4 val7 **want to return this row only
2 val1 val4 val8
3 val1 val4 val8
4 val1 val5 val9
5 val2 val5 val9
6 val2 val5 val9
7 val2 val6 val0
8 val3 val6 val0
How do I use SQL (with mySQL) to return just the rows that have multiple of the same value in col1 with multiple of the same value in col2 but with a unique value in col 3?
In the table above (exTab), for instance, val1 occurs 4 times in col1, and for these 4 occurrences val4 occurs 3 times in col2, but for these 3 occurrences val7 occurs only once in col3, so I would want to return this row (row 1). Given the criteria, row 1 would be the only row I would want to return from this table.
I've tried various combinations with group by, having count > 1, distinct, where not exits, and more to no avail. This is my first post, so my apologies if I've done something incorrectly.
I would do this by combining the results of two subqueries:
In subquery 1 I would get the col1-col2 combinations which occur more than once.
In subquery 2 I would get the col1-col2-col3 combinations that occur only once.
The intersection (inner join) of these 2 subqueries would yield the record you are looking for.
select t1.*
from
exTab t1
inner join
(select col1, col2 from exTab
group by col1, col2
having count(*)>1) t2
inner join
(select col1, col2, col3 from exTab
group by col1, col2, col3
having count(*)=1) t3 on t2.col1=t3.col1
and t2.col2=t3.col2
and t1.col1=t3.col1
and t1.col2=t3.col2
and t1.col3=t3.col3
If I've good understand the problem this SQL query might help you:
SELECT
SubTab.PK
FROM
(SELECT
PK,
COUNT(col3) OVER (PARTITION BY col1) as col1_group,
COUNT(col3) OVER (PARTITION BY col2) as col2_group
FROM
exTab) SubTab
WHERE
SubTab.col1_group = 1 AND SubTab.col2_group = 1;
It will run TWO windowing aggregating functions over original Tab, and then return temporary tab and from this tab we only select this PK of rows for which col3 was unique in one group and the another too.
You could try something along the lines of:
SELECT
*
FROM table
WHERE col1 IN (SELECT col1 FROM table GROUP BY 1 HAVING count(*)>1)
AND col2 IN (SELECT col2 FROM table GROUP BY 1 HAVING count(*)>1)
AND col3 IN (SELECT col3 FROM table GROUP BY 1 HAVING count(*)=1)
Though the performance may be terrible if your table is large.
I would like to divide multiple column with 2 statements as the following:
TBL1
NAME VAL1 VAL2 VAL3
A 2 3 3
TBL2
NAME VAL1 VAL2 VAL3
B 2 3 3
ERROR SCRIPT
select (select * from tbl1)/(select * from TBL2) as result
Result that i need as the following:
VAL1 VAL2 VAL3
2/2 3/3 3/3
There should be a ON clause but not sure what it should be
SELECT t1.VAL1/t2.VAL1, t1.VAL2/t2.VAL2, t1.VAL3/t2.VAL3,
FROM TBL1 t1, TBL2 t2
The best thing that I can come up with is
SET #COUNTER1 = 0;
SET #COUNTER2 = 0;
SELECT T1.VAL1 / T2.VAL1,
T1.VAL2 / T2.VAL2,
T1.VAL3 / T2.VAL3
FROM (SELECT *, (#COUNTER1 := #COUNTER1 + 1) AS id FROM TBL1) AS T1
INNER JOIN (SELECT *, (#COUNTER2 := #COUNTER2 + 1) AS id FROM TBL2) AS T2
ON T1.id = T2.id
Select Tbl1.Val1 / Tbl2.Val1 As Val1
, Tbl1.Val2 / Tbl2.Val2 As Val2
, Tbl1.Val3 / Tbl2.Val3 As Val3
From Tbl1
Cross Join Tbl2
Of course, this probaly isn't what you want. Firstly, there is nothing that correlates the rows in Table 1 with the rows in Table 2. I.e., if both tables have three rows each, the result will have nine rows. In short, you will get a Cartesian product between the two tables. Second, there is no logic to deal with dividing by zero errors. Should those values simply be set to zero? Should they be null?
MySQL Join Syntax. (Yes MySQL supports the ISO/ANSI standard Cross Join syntax).
SQL Fiddle version
Edit
If what are trying to do is to concatenate the values into a string expression of #/#, then you need to use the Concat function:
Select Concat(Tbl1.Val1,'/',Tbl2.Val1) As Val1
, Concat(Tbl1.Val2,'/',Tbl2.Val2) As Val2
, Concat(Tbl1.Val3,'/',Tbl2.Val3) As Val3
From Tbl1
Cross Join Tbl2
SQL Fiddle version.
I have a table name T1 having only one Column name Col1 having rows –
Col1
a
b
c
And another table name T2 also having only one Column name Col1 having rows –
Col1
x
y
z
Now I want record like
Col1--Col2
a------x
b------y
c------z
I am using mysql.
Thanks in advance!!
create table T1(col1 varchar(10));
insert T1 values ('a'),('b'),('c');
create table T2(col2 varchar(10));
insert T2 values ('x'),('y'),('z');
select A.col1, B.col2 from
(select #r:=#r+1 rownum, col1 from (select #r:=0) initvar, T1) A,
(select #s:=#s+1 rownum, col2 from (select #s:=0) initvar, T2) B
where A.rownum=B.rownum
Because there is no ORDER BY clause, you are depending on luck and convention for the row numbering to be according to the order inserted. It may not always be the case.
In your example, if you want to join the tables to get row results like this:
Row 1 - A,X
Row 2 - B,Y
Row 3 - C,Z
..then you will have to add a common field that you can JOIN the two tables on.
If you want to be able to return results from both tables like this:
Row 1 - A
Row 2 - B
Row 3 - C
Row 4 - X
Row 5 - Y
Row 6 - Z
.. then you will need to use a UNION:
(SELECT Col1 FROM T1) UNION (SELECT Col1 FROM T2)