MySQL take from One Row and Create Two Rows - mysql

This might sound a little unorthodox but I haven't been able to find out if this even works. I have a MySQL query that fills columns into a single row.
Select
projectnumber,
highnumber,
lownumber
From
Table1
WHERE
project = 'THIS'
and sequence = '0'
This would return on 1 row with 3 columns "projectnumber", "highnumber", "lownumber". I am needing to return 2 rows, both would have the same "projectnumber" but one row would have "highnumber", and the second row would have the "lownumber" with an "A" appended to the end of it.
Is this even plausible?

Use UNION ALL to "mix" two statements, and use CONCAT() to append "A" to a cloumn:
SELECT projectnumber, highnumber FROM Table1 WHERE ...
UNION ALL SELECT projectnumber,CONCAT(lownumber,"A") FROM Table1 WHERE ...

Related

Query with offset returns overlapping data sets

Initial attempts at getting a very simple pagination, using fetch n rows and then a subsequent call with offset, gives overlapping entries in Oracle.
I was expecting the following to give me two unique sets of results. 1-100 and then 101-200 of the results that would have been returned if the first line had been set with a limit of 200.
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" fetch first 100 rows only ;
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" offset 100 rows fetch next 100 rows only ;
So if there are 150 items for approver A the first results should be:
A, item1
....
A, item100
The subsequent call (offset by 100) giving
A, item101
...
A, item150
B, item1
B, item2
....
B, item201
Unfortunately the second set contains some entries from the first batch of values. Probably a really silly error, but I can't find an explanation as to why this should happen.
---- Updated as a result of comments
The Primary key consists of Approver and several other fields which together form a composite and unique primary.
The code will be called through ODBC and will be used on Oracle and MySQL back-end.
In Oracle, if you make "order by" to a column containing same values (like you have - 'A', 'A', 'A' ...) the order of records inside 'A' values will be random.
Please try to change your queries to ... order by "APPROVER", rowid ...
Presumably, APPROVER is not a unique column. Since there may be duplicates, the order by claus is not stable, and the offset clause might generate duplicates.
A simple solution is to add more columns to the order by to break the ties. Assuming that (approver, item) is a unique set of columns, that would be:
select *
from appr
where approver = 'A' or approver > 'A'
order by approver, item
fetch first 100 rows only
-- then: offset 100 rows fetch next 100 rows only
Notes:
there is no need to surround all-caps identifiers (tables or column names) with double quotes: that's the default in Oracle already
parentheses around the or conditions are superfluous in this simple case
if approver is always one character long, then the where clause can be simplified as where approver >= 'A'
use index hints only if you really know why you are doing it (I am not saying you don't, but I removed it, just in case); most of the time, the database knows better

Generate MQsql query to get records

I am having the following table say "A"
"column1" "column2"
1 arafath#gmail.com
2 ram#gmail.com;arafath#gmail.com
3 tom#gmail.com
I want to get the records with the following condition.
Condition1:
If the column value exist in the any of the row, it will retrieve the matched rows
Condition2:
If the column value doesn't match with any of the row, it wants to retrieve all the rows
Eg: column2 = "ram#gmail.com"
Output should be "row 2"
Eg: column2 = "arafath#gmail.com"
Output should be "row 1, row 2"
Eg: column2 = "xxx#gmail.com" (Unmatched column)
Output should be all the rows (row 1, row 2, row 3)
Please help me out to solve the problem.
Thanks in advance.
Please try the below one.
SELECT col1, col2
FROM yourTable
where ( not exists (Select col2
FROM yourTable where col2 like 'xxx#gmail.com')
or col2 like 'xxx#gmail.com');
We can try using a union here:
SELECT col1, col2
FROM yourTable
WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]'
UNION ALL
SELECT col1, col2
FROM yourTable
WHERE col2 NOT REGEXP '[[:<:]]ram#gmail.com[[:>:]]' AND
NOT EXISTS (SELECT 1 FROM yourTable WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]');
Demo
The above strategy is that the first half of the union returns the matching record, if it exists. The second half of the union then returns all other records, but only if on match were found in the first half of the union. If a match were found, then the WHERE clause in the second half of the union would fail, and would return nothing.
Also, please note that storing comma separated (or semicolon separated) data in your MySQL tables is generally bad practice. I had to use REGEXP to get around this problem, but ideally if each email had a separate row, we would only need to use = equality.

How to return NULL when result is empty?

I have a simple query that selects one field and only one row, thus one value.
Is there any way to make it return NULL if the query results in an empty set? Instead of returning zero rows?
I think I need to use something with NOT EXISTS, THEN NULL but not certain about it.
select
(Your entire current Select statement goes here) as Alias
from
dual
dual is a built in table with a single row that can be used for purposes like this. In Oracle this is mandatory. MySQL supports it, but you can also just select a single value without specifying a table, like so:
select
(Your entire current Select statement goes here) as Alias
In either case you're selecting a single value. This means that:
If your select returns one value, that value is returned.
If your select statement returns one column, but no rows, NULL will be returned.
If your select statement returns multiple columns and/or multiple rows, this won't work and the query fails.
An easy way to do this is with aggregation:
select max(col)
from t
where <your condition here>
This always returns one row. If there is no match, it returns NULL.
Late reply but I think this is the easiest method:
SELECT
IFNULL((SELECT your query), NULL)
Use a UNION with a NOT EXISTS(original where clause)
select col1
from mytable
where <some condition>
union
select null
where not exists (
select * from mytable
where <some condition>)
You can use COALESCE for example:
SELECT COALESCE(Field1,NULL) AS Field1 FROM Table1
Edit 1:
sorry i mistake with return field as null not result set,for result set return as null use Union and Exist Function like this:
SELECT NULL AS Field1 FROM Table1 WHERE not EXISTS(SELECT Field1 FROM Table1 WHERE Field2>0)
UNION
SELECT Field1 FROM Table1 WHERE Field2>0

In mysql, can I count how many rows satisfy some condition, if not then exit the count?

Basically I store data in MySql 5.5. I use qt to connect to mysql. I want to compare two columns, if col1 is greater than col2, the count continues, but when col1 is less than col2, count finishes and exits. So this is to count how many rows under some condition at the beginning of column. Is it possible in mysql?
An example:
Col1 Col2
2 1
2 3
2 1
The count I need should return 1, because the first row meets the condition of Col1 > Col2, but the second row doesn't. Whenever the condition is not meet, counting exits no matter if following rows meet the condition or not.
SELECT COUNT(*)
FROM table
WHERE col1 > col2
It's a little difficult to understand what you're after, but COUNT(*) will return the number of rows matched by your condition, if that's your desire. If it's not, can you maybe be more specific or show example(s) of what you're going for? I will do my best to correct my answer depending on additional details.
You should not be using SQL for this; any answer you get will be chock full of comprimise and if (for example) the result set from your intial query comes back in a different order (due to an index being created or changed), then they will fail.
SQL is designed for "set based" logic - and you really are after procedural logic. If you have to do this, then
1) Use a cursor
2) Use an order by statement
3) Cross fingers
This is a bit ugly, but will do the job. It'll need adjusting depending on any ORDER etc you would like to apply to someTable but the principle is sound.
SELECT COUNT(*)
FROM (
SELECT
#multiplier:=#multiplier*IF(t.`col1`<t.`col2`,0,1) AS counter
FROM `someTable` t, (SELECT #multiplier := 1) v
HAVING counter = 1
) scanQuery
The #multiplier variable will keep multiplying itself by 1. When it encounters a row where col1 < col2 it multiplies by 0. It will then continue multiplying 0 x 1. The outer query then just sums them up.
It's not ideal, but would suffice. This could be expanded to allow you to get those rows before the break by doing the following
SELECT
`someTable`.*
FROM `someTable`
INNER JOIN (
SELECT
`someTable`.`PrimaryKeyField`
#multiplier:=#multiplier*IF(`col1`<`col2`,0,1) AS counter
FROM `someTable` t, (SELECT #multiplier := 1) v
HAVING counter = 1
) t
ON scanQuery.`PrimaryKeyField` = `someTable`.`PrimaryKeyField`
Or possibly simply
SELECT
`someTable`.*
#multiplier:=#multiplier*IF(`col1`<`col2`,0,1) AS counter
FROM `someTable` t, (SELECT #multiplier := 1) v
HAVING counter = 1

SQL: How do I select one of two fields, depending on a third field

I need to export data from an existing TABLE. Till recently I used -
SELECT item_ID, item_Info, ...moreFields... FROM tableName WHERE myCondition=0
Now, they changed the TABLE structure, and added new field "item_Info2"
When they fill in the TABLE:
if "item_Type" is 1 or 2 or 3 or 4, then "item_Info" is relevant
if "item_Type" is 5, then "item_Info" is empty, and I need "item_Info2" as my query result, instead of "item_Info"
What is the corresponding SELECT command?
[similiar question: mysql select any one field out of two with respect to the value of a third field
but from this example I cannot see the syntax for selecting moreFields ]
Thanks,
Atara.
You can treat the CASE statement as any other column name, separate it from the other columns with a comma, etc. What happens in the CASE should be considered a single column name, in your case you need commas before and after it.
SELECT item_ID, CASE WHEN item_Type = 5 THEN item_info ELSE item_info2 END, field_name, another_field_name ...moreFields... FROM tableName WHERE myCondition=0
you could also use an alias to be easier to get the result from the query:
SELECT item_ID, CASE WHEN item_Type = 5 THEN item_info ELSE item_info2 END AS 'item_info', field_name, another_field_name ...moreFields... FROM tableName WHERE myCondition=0
To edit the reply on the other question:
SELECT
item_id, item_otherproperty,
CASE WHEN item_Type= 5
THEN item_Info2
ELSE item_Info
END AS `info` FROM table ...