I'm new to MySql and I need to append the results of two independently ordered queries, limit the result of the whole thing combined, and return starting at a certain index.
So something like this
the first query will result in an ordered list like this
a
b
c
the second query will result in another ordered list like this
1
2
3
Then append the second result after the first like this
a
b
c
1
2
3
Then only return a certain number of elements and start at a particular index, so for example I only want total 4 return values starting at index 2, the result should be
c
1
2
3
As you can see, "c" is at index 2 of the appended result, and 4 elements are returned.
Anybody knows how to write this complicated MySQL statement?
For the first part of your problem, you could use a UNION
UNION is used to combine the result from multiple SELECT statements into a single result set.
Read more here
As for the second part of your problem, you could use LIMIT. Read this SO Answer
Now to combine the both, lets say you have two tables - tbl1 and tbl2 as
tbl1 tbl2
a 1
b 2
c 3
You could use a query as follows:
SELECT * FROM (SELECT * FROM tbl1 UNION SELECT * FROM tbl2) as t
LIMIT 2, 9430903;
The second number in the limit clause is just a very large number. So this query will retrieve all rows from the 3rd row to the last row.
Hope this helps.
Related
could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference
I have a comma separated list of IDs that I have to use inside of an IN() clause in mysql (Percona Xtra DB), similar to this:
SELECT sum(p_views) as total_views FROM table WHERE id IN (1,1,3,5,5,5,7)
In the example above, the ids 1 and 5 will be summed only once, instead of the number of actual occurrences. The number of duplicates is unknown, and can range from 2 to 20000.
How would I have mysql treat them as unique numbers, and sum them accordingly no matter if they are all unique, or if the list is comprised of a single ID, 20000 times?
This can't be done with an IN () predicate. That will only check whether a given row satisfies the predicate or not; it won't "duplicate" the rows returned.
To get "duplicate" rows returned (so values can be accumulated in a SUM() aggregate), you'd need another row source.
One option would be to use a JOIN operation to an inline view, instead of the IN() list predicate.
SELECT SUM(t.p_views) AS total_views
FROM table t
JOIN
( SELECT 1 AS id
UNION ALL SELECT 1
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 5
UNION ALL SELECT 5
UNION ALL SELECT 5
UNION ALL SELECT 7
) c
ON c.id = t.id
Another (likely more efficient) option (if there are lots of repeated values) would be to use a "count" in place of repeating the values, and multiply, e.g.
SELECT SUM(t.p_views*c.cnt) AS total_views
FROM table t
JOIN
( SELECT 1 AS id, 2 AS cnt
UNION ALL SELECT 3 , 1
UNION ALL SELECT 5 , 3
UNION ALL SELECT 7 , 1
) c
ON c.id = t.id
If this information is already available in another row source, you might be able to get improved performance by making use of that row source in the query (if an appropriate index is available), and avoid generating the messy "hardcoded" UNION ALL inline view, which won't be indexed (unless Percona has already implemented indexes for inline views.)
I'm sure there are other approaches.
But bottom line, it can't be done with an IN() list predicate. The results from a query with this:
WHERE id IN (1)
will be the same as results of a query with this:
WHERE id IN (1,1,1,1)
Because, for each row, both of those predicates will either evaluate to TRUE, FALSE or NULL. There's no way to return the "number of times" an item matched from an IN() comparison.
I have a table which has only 3 columns. When I type the following query
select * from MyTable order by 5 and 2;
I get every thing in the table( The result is equal to that of select * from MyTable; ). What I originally expected is that I would get some kind of error. But I didn't get it, why?
order by 5 and 2 is interpreted as order by (5 and 2) which is a constant expression, hence no real ordering is done and data is simply shown in the order it was inserted.
What is happenning here is that 5 and 2 is seen as an expression which is evaluated to 1. However, it shouldn't give a result sorted by first column.
Actually, I think you only get sorted data because you inserted it in sorted sequence. Take a look at this SQLFiddle:
http://sqlfiddle.com/#!2/3e04e/1
The data is not sorted by any of the columns, it is being sorted by a value 1.
5 and 2 are column indexes and they mean 5th column and 2nd column.
select * from MyTable order by 5,2;
It means start with index 5 and bring 2record i.e 5,6,7
I have a table that include 3 fields (among others) that for each of them that is equal to 1 I need the query to return a record.
So, if all 3 fields are equal to 1 the query should give 3 records.
If two fields (any of the three) are equal to 1 the query should return 2 records and so on.
How would a query like that look?
This should do what you need:
SELECT * from table WHERE field1=1
UNION ALL
SELECT * from table WHERE field2=1
UNION ALL
SELECT * from table WHERE field3=1
The logic is that we select the rows we need for each criteria one by one, and then create an union of them. It is true however, that this does not scale nice... Then again, I have never ever faced this requirement "out in the wild"...
Can anyone help me on how could I join two tables without merging the result into single row? Please see below query:
SELECT *
FROM resorderdetails rd
INNER JOIN resinvalidorderdetails ri
ON rd.itemid=ri.srcitemid;
Let say for example I have 1 row in resorderdetails table with field itemid=1 and I have 1 row in resinvalidorderdetails table with field srcitemid=1.
If we will going to execute the above query, it will return a result of single row [merging the data of two tables]
What I want to do is to have two rows as a result. The first row is the record came from resorderdetails and the other row is the record came from resinvalidorderdetails without using UNION ALL or UNION.
How could I do it? Is it possible?
It's not possible, because you wannna have :
SELECT * FROM resorderdetails rd
and
select * from resinvalidorderdetails
There are only joins operations and UNION which you don't want to use, and the JOINS will put together or remove commons ids and UNION will do exactly what you want
Beside to display a query with 2+ tables you need something in common(even the union need same number of columns).