Mysql diversified results - mysql

I got table in db in following way:
id Name Type
1. Aero. Product
2. Ddd. Product
3. Sass. Image
4. Rrrrr. Image
This is just to understand and actual table in much bigger scale.
So the question is how to get diversfied results so the product type wont be like product,product, image, image
If i will do select * from table where 1 order by ‘id’
Results having grouped “type”
I want have results like
1 blabla product
3 blabla image
2 blabla product
4 blabla image
So the records with same type will be spreaded over results and
As much as possible wont stay together

As already suggested its better if you do this type of sorting in your application code, In Mysql you can do this by using user defined variables.
First break your data according to your types, get data for products and assign a row number and do the same with second data set for type image and then merge these sets using union operation and then sort them by row number
select *
from(
select d1.*, #row1:= #row1 + 1 as row
from demo d1,
(select #row1:=0) t1
where `Type` = 'Product'
union all
select d2.*, #row2:= #row2 + 1 as row
from demo d2,
(select #row2:=0) t2
where `Type` = 'Image'
) t
order by t.row, t.Type desc
demo

Related

How to insert SUM() function that sums rows with similar ID in a code part of witch is unchangeable?

I am trying to write a quarry in a module for Dolibarr ERP. But module hase a part of code that is predefined and can not be changed. And I need to insert a SUM() function in it that will combine rows with similar id. That i know how to do in a regular MySQL:
SELECT fk_product AS prod, SUM(value) AS qty
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
ORDER BY 1 DESC
LIMIT 26
that gives me what I want :
prod qty
1 13
2 10
BUT module has a predefined unchangeable code :
this part is predefined module writes it himself based on values provider in it:
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
THIS PART I CAN WRITE IN A MODULES GUI:
FROM
llx_stock_mouvement AS c
WHERE
type_mouvement = 2
AND label LIKE 'SH%'
And this part is predefined:
ORDER BY 1 DESC
LIMIT 26
I would appreciate any help and advice on question is there any workaround that can be done to make my desired and result ampere ? As it would using the first code I posted ?
If you can only modify the bit in the middle box then you might need to use a subquery;
--fixed part
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
--begin your editable part
FROM
(
SELECT fk_product,
SUM(value) AS value
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
) c
--end your editable part
--fixed part
ORDER BY 1
DESC
LIMIT 26

Comparing attributes from the same table using SQL query

I have a contents table and the entires in it are as shown in the attached figure
There are more than 100,000 entries. I want to fetch the data where the update_date for commit=0 is greater than update_date for commit=1. I also need the corresponding row for commit=1.
I tried a few things, but takes a long time to retrieve the results. What is the best SQL query I can use. I am using MySQL database.
EDIT
I have now updated the table. There is an attribute called content_id which binds the rows together.
A query like this gives me half of what I want
select a.* from contents a, contents b where
a.content_id=b.content_id and
a.update_date > b.update_date and
a.committed=0 and b.committed=1
I also want the corresponding entries from committed=1, but they should be appended at the bottom as rows and not vertically concatenated as columns.
For example, I cannot use
select * from contents a, contents b where
a.content_id=b.content_id and
a.update_date > b.update_date and
a.committed=0 and b.committed=1
because the results from 'b' are appended vertically. Also, is there a better way to write this query. This works really slow if there are many entries in the database.
I am assuming that in the above example, you only need id=2 as for content id = 1, the update_date for commit=0 is greater than update_date for commit=1 and in that case you need data for commited = 1.
I an using Oracle, so you need to find a suitable replacement for row_number() funtion in mysql.
The logic would be
Create a view on the existing table to use rownumber so it will give rownumber like below order by time desc (see if you use a nested query to do it)
ID, CONTENT_ID, COMMITED, UPDATE_DATE, ROWN
2 1 1 06-SEP-15 00:00:56 1
1 1 0 07-SEP-15 00:00:56 2
3 2 0 03-SEP-15 00:00:56 1
4 2 1 04-SEP-15 00:00:56 2
Now select only rows where where rown=1 and commited=1
This is the query in oracle. The second with query c2 will be your view.
Oracle query
with c1 (id, content_id,commited,update_date) as
(
select 1,1,0,sysdate from dual union
select 2,1,1,sysdate-1 from dual union
select 3,2,0,sysdate-4 from dual union
select 4,2,1,sysdate-3 from dual
),
c2 as
(select c1.*,row_number() over(partition by content_id order by update_date) as rown from c1)
select id,content_id,commited,update_date from c2
where rown=1 and commited=1
ID, CONTENT_ID, COMMITED, UPDATE_DATE, ROWN
Output
ID, CONTENT_ID, COMMITED, UPDATE_DATE
2 1 1 06-SEP-15 00:06:17

MySQL multi-step GROUP BY without subquery

I'm working on improving some queries I inherited, and was curious if it was possible to do the following - given a table the_table that looks like this:
id uri
---+-------------------------
1 /foo/bar/x
1 /foo/bar/y
1 /foo/boo
2 /alpha/beta/carotine
2 /alpha/delic/ipa
3 /plastik/man/spastik
3 /plastik/man/krakpot
3 /plastik/man/helikopter
As an implicit intermediate step I'd like to group these by the 1st + 2nd tuple of uri. The results of that step would look like:
id base
---+---------------
1 /foo/bar
1 /foo/boo
2 /alpha/beta
2 /alpha/delic
3 /plastik/man
And the final result would reflect the number of unique tuple1 + tuple2 values, per unique id:
id cnt
---+-----
1 2
2 2
3 1
I can achieve these results, but not without doing a subquery (to get the results of the implicit step mentioned above), and then select/grouping out of that. Something like:
SELECT
id,
count(base) cnt
FROM (
SELECT
id,
substring_index(uri, '/', 3) AS base
FROM the_table
GROUP BY id, base
)
GROUP BY id;
My reason for wanting to avoid the subquery is that I'm working with a fairly large (20M rows) data set, and the subquery gets very expensive. Gut tells me it's not doable, but figured I'd ask SO...
There's no need for a subquery -- you can use count with distinct to achieve the same result:
SELECT
id,
count(distinct substring_index(uri, '/', 3)) AS base
FROM the_table
GROUP BY id
SQL Fiddle Demo
BTW -- this returns count of 1 for id 3 -- I assume that was a typo in your posting.

How to select vertical data in MySQL table

If I have a table like this:
ID color size weight
1 red 2 3
2 green 4 5
So to run a mysql query to find the ID number that is color:red and size:2 and weight:3 I can do this:
select ID from table where color=red AND size=2 AND weight=3
As properties are growing in addition to color, weight, size, mileage, speed, etc... and I want to keep the table scaling it would make sense to organize it this way
ID ID2 property value
1 1 color red
2 1 size 2
3 1 weight 3
4 2 color green
5 2 size 4
6 2 weight 5
How do I run a select query here to find the ID number that is color:red and size:2 and weight:3
For key value structure one approach is to self join as many times as the no. of properties you have like in your case 3 properties (color,weight,size) so you need 2 self joins and for each,filter results according to properties like in below query i have given unique aliases so for the alias t i have filtered rows with t.property = 'color' and for value t.value = 'red' and same as for other aliases to find the desired ids which fits for the provided criteria,So if your criteria increases with another property you need another self join and same filtering as above
select t.id2
from test t
join test t1 on(t.id = t1.ID2)
join test t2 on(t.id = t2.ID2)
where t.property = 'color'
and t1.property = 'size'
and t2.property = 'weight'
and t.value = 'red'
and t1.value = '2'
and t2.value = '3'
DEMO
If there's a lot of properties (only a few of which may be of interest), you may be better off with the Star schema that was specifically invented for this case.
Less than 10 properties you described are hardly a justification for such complication though. You'll be just fine with the initial table in accordance with the KISS principle.

WHERE clause in SSRS expression for max function

I have for example a query with return something as it
route value
1 3
2 2
3 4
4 5
5 1
then I need to put in 2 textbox the max and the min route so in sql this would be
select top 1 route from table where value=(select max(value) from table)
I add a image done in excel, how this would be.
I believe this is so easy but I dont have idea how to get it.
I got using expression, this was extactly expression
="Route "+
Convert.ToString (
Lookup(max(fields!value.Value),fields!value.Value ,fields!route.Value,"mydataset")
)
changing max for min, for the other...
thanks everyone.
I believe the query you're looking for would be:
With Min_Max_CTE as (
Select MIN(value) as Min_Value
, MAX(value) as Max_Value
From Table
)
Select Top 1 'Min' as Type
, T.route
, T.value
From Table T
Inner Join Min_Max_CTE CTE
on T.value = CTE.Min_Value
Union All
Select Top 1 'Max' as Type
, T.route
, T.value
From Table T
Inner Join Min_Max_CTE CTE
on T.value = CTE.Max_Value
Order by Type desc --This will put the Min Route first followed by the Max Route
Then, put that query into a dataset, and then create a tablix and use the Type, route, and value fields to return the minimum route and the maximum route. It should end up being set up just like your excel section with the min and max routes above.
You can do this SSRS by using a couple of separate tables. Your example data:
And two tables in the Designer:
Since the tables only have header rows, only the first row in the table will be displayed.
To make sure we get the MAX and MIN values in the two tables, each table needs to order its Dataset appropriately, i.e. by Value by descending and ascending respectively.
MAX table:
MIN table:
Which gives your expected result: