Why is "group by" giving only one column as output? - monetdb

I have a table something like this:
ID|Value
01|1
02|4
03|12
01|5
02|14
03|22
01|9
02|32
02|62
01|13
03|92
I want to know how much progress have each id made (from initial or minimal value)
so in sybase I can type:
select ID, (value-min(value)) from table group by id;
ID|Value
01|0
01|4
01|8
01|12
02|0
02|10
02|28
02|58
03|0
03|10
03|80
But monetdb does not support this (I am not sure may be cz it uses SQL'99).
Group by only gives one column or may be average of other values but not the desired result.
Are there any alternative to group by in monetdb?

You can achieve this with a self join. The idea is that you build a subselect that gives you the minimum value for each id, and then join that to the original table by id.
SELECT a.id, a.value-b.min_value
FROM "table" a INNER JOIN
(SELECT id, MIN(value) AS min_value FROM "table" GROUP BY id) AS b
ON a.id = b.id;

Related

Oracle select rows from a query which are not exist in another query

Let me explain the question.
I have two tables, which have 3 columns with same data tpyes. The 3 columns create a key/ID if you like, but the name of the columns are different in the tables.
Now I am creating queries with these 3 columns for both tables. I've managed to independently get these results
For example:
SELECT ID, FirstColumn, sum(SecondColumn)
FROM (SELECT ABC||DEF||GHI AS ID, FirstTable.*
FROM FirstTable
WHERE ThirdColumn = *1st condition*)
GROUP BY ID, FirstColumn
;
SELECT ID, SomeColumn, sum(AnotherColumn)
FROM (SELECT JKM||OPQ||RST AS ID, SecondTable.*
FROM SecondTable
WHERE AlsoSomeColumn = *2nd condition*)
GROUP BY ID, SomeColumn
;
So I make a very similar queries for two different tables. I know the results have a certain number of same rows with the ID attribute, the one I've just created in the queries. I need to check which rows in the result are not in the other query's result and vice versa.
Do I have to make temporary tables or views from the queries? Maybe join the two tables in a specific way and only run one query on them?
As a beginner I don't have any experience how to use results as an input for the next query. I'm interested what is the cleanest, most elegant way to do this.
No, you most probably don't need any "temporary" tables. WITH factoring clause would help.
Here's an example:
with
first_query as
(select id, first_column, ...
from (select ABC||DEF||GHI as id, ...)
),
second_query as
(select id, some_column, ...
from (select JKM||OPQ||RST as id, ...)
)
select id from first_query
minus
select id from second_query;
For another result you'd just switch the tables, e.g.
with ... <the same as above>
select id from second_query
minus
select id from first_query

ORA-00904: invalid column name but I am using the correct column name

Can someone see where I am going wrong in the below query? I am getting the error message that the GROUP BY column doesn't exist, but it clearly does as I see that column name in the output when I don't use the GROUP BY.
SELECT
(SELECT customer_address.post_code FROM customer_address WHERE customer_address.address_type = 0 AND customer_address.customer_no = orders.customer_no) postcode, SUM(orders.order_no) orders
FROM
orders, customer_address
WHERE
orders.delivery_date = '27-MAY-15'
GROUP BY
postcode;
The answer is: You cannot use an alias name in GROUP BY.
So:
GROUP BY (SELECT customer_address.post_code ...);
Or:
select postcode, sum(order_no)
from
(
SELECT
(SELECT customer_address.post_code FROM customer_address WHERE customer_address.address_type = 0 AND customer_address.customer_no = orders.customer_no) postcode,
orders.order_no
FROM orders, customer_address
WHERE orders.delivery_date = '27-MAY-15'
)
GROUP BY postcode;
EDIT:
However, your query seems wrong. Why do you cross-join orders and customer_address? By mistake I guess. Use explicit joins (INNER JOIN customer_address ON ...), when using joins to avoid such errors. But here I guess you'd just have to remove , customer_address.
Then why do you add order numbers? That doesn't seem to make sense.

cascading Input Control sql query return error: "ORA-01427: single-row subquery returns more than one row"

looking for solution on my sql query error.I'm trying to create second cascading Input Control in JaspersoftServer. The first Input Control works fine, however when I try to create a second cascade IC it returns with the error. I have 3 tables (user, client, user_client), many to many, so 1 linked table (user_client) between them.The 1st Input Control (client) - works well, end user will select the client, the client can have many users, so cascade is the key. Also, as the output, I would like to get not the user_id, but user's firstname and the lastname as one column field. And here is where i'm stuck. I'm pretty sure it is simple syntaxis error, but spent a good couple of hours to figure out what is wrong with it. Is anyone can have a look at it please and indicate where is the problem in my query ?! So far I've done:
select distinct
u.user_id,(
SELECT CONCAT(first_name, surname) AS user_name from tbl_user ),
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
Thank you in advance.
P.S. JasperServer + Oracle 11g
You're doing an uncorrelated subquery to get the first/last name from the user table. There is no relationship between that subquery:
SELECT CONCAT(first_name, surname) AS user_name from tbl_user
... and the user ID in the main query, so the subquery will attempt to return every first/last name for all users, for every row your joins find.
You don't need to do a subquery at all as you already have the tbl_user information available:
select u.user_id,
CONCAT(u.first_name, u.surname) AS user_name
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
If you want to put a space between the first and last name you'll either need nested concat() calls, since that function only takes two arguments:
select u.user_id,
CONCAT(u.first_name, CONCAT(' ', u.surname)) AS user_name
...
... or perhaps more readably use the concatenation operator instead:
select u.user_id,
u.first_name ||' '|| u.surname AS user_name
...
If the first control has selected a client and this query is supposed to find the users related to that client, you're joining the tables the wrong way round, aren't you? And you aren't filtering on the selected client - but no idea how that's actually implemented in Jasper. Maybe you do want the entire list and will filter it on the Jasper side.

Vertica subquery with limit

I found problem in writing subquery with limit 1 to get the top record.
Here is my problem example.
Table Master(id,set)
Table Detail(id,set,code)
i am trying to get the latest code for each set in Master table.
Following is the query which i tried but got an error that limit 1 is not supported for correlated subqueries and it should contain GROUP By clause.
select id,set,(select code from detail where set=master.set order by id desc limit 1) from master;
And the result wolud be like
please help me if this is wrong way, i am new to this vertica database.
thnk you.
I'm not sure about that particular error, but you can use the rank() analytic function to produce results like this:
select id, set, code from (
select M.id, D.set, D.code, rank() over (partition by D.set order by D.id desc) as rank
from detail as D
right outer join master as M
on D.set = M.set) as ranks
where rank = 1
order by id;
The inner subquery uses the rank() function to assign a rank to each row within a set. The outer query just picks out rows with rank 1.

How do I write a LINQ query to combine multiple rows into one row?

I have one table, 'a', with id and timestamp. Another table, 'b', has N multiple rows referring to id, and each row has 'type', and "some other data".
I want a LINQ query to produce a single row with id, timestamp, and "some other data" x N. Like this:
1 | 4671 | 46.5 | 56.5
where 46.5 is from one row of 'b', and 56.5 is from another row; both with the same id.
I have a working query in SQLite, but I am new to LINQ. I dont know where to start - I don't think this is a JOIN at all.
SELECT
a.id as id,
a.seconds,
COALESCE(
(SELECT b.some_data FROM
b WHERE
b.id=a.id AND b.type=1), '') AS 'data_one',
COALESCE(
(SELECT b.some_data FROM
b WHERE
b.id=a.id AND b.type=2), '') AS 'data_two'
FROM a first
WHERE first.id=1
GROUP BY first.ID
you didn't mention if you are using Linq to sql or linq to entities. However following query should get u there
(from x in a
join y in b on x.id equals y.id
select new{x.id, x.seconds, y.some_data, y.type}).GroupBy(x=>new{x.id,x.seconds}).
Select(x=>new{
id = x.key.id,
seconds = x.Key.seconds,
data_one = x.Where(z=>z.type == 1).Select(g=>g.some_data).FirstOrDefault(),
data_two = x.Where(z=>z.type == 2).Select(g=>g.some_data).FirstOrDefault()
});
Obviously, you have to prefix your table names with datacontext or Objectcontext depending upon the underlying provider.
What you want to do is similar to pivoting, see Is it possible to Pivot data using LINQ?. The difference here is that you don't really need to aggregate (like a standard pivot), so you'll need to use Max or some similar method that can simulate selecting a single varchar field.

Resources