"Merge" two sheets AND do math in one column - filter

I have two sheets that have basically the same layout (a couple of columns are rearranged). What I'm wanting to do is take the data from one sheet and combine it with another. The trick that's keeping me from just FILTERing it and being done with it is that the "Qty" column needs to do some math.
The first sheet lists all items. The second lists "adjustments". So I might reduce one item by 50% or 100%. The goal is that the math will appear on this third/merged sheet and if an item is reduced by 100%, it will be completely removed.
projectTasks!A,B,C,D,E,G
projectTasksAdj!A,B,C,D,F,E
Adding projectTasks!E to projectTasksAdj!F
Main data sheet: projectTasks
Adjustments: projectTasksAdj
Merged sheet: reportsTasks
The columns are out of order in projectTasksAdj just for searching purposes.
Here's my sheet
Thank you very much for any guidance!

=ARRAYFORMULA(QUERY({A2:C4;
B8:B9, A8:A9, C8:C9*-1},
"select Col1,Col2,sum(Col3)
where Col1 is not null
group by Col1,Col2
label sum(Col3)''", 0))

=arrayformula(QUERY(QUERY({projectTasks!A3:D,value(projectTasks!E3:E),projectTasks!F3:G;projectTasksAdj!A3:D,projectTasksAdj!G3:G,projectTasksAdj!I3:I,projectTasksAdj!E3:E},"Select Col1, Col2, Col3, Col4, Sum(Col5), Col6, Col7 where Col1 is not null group by Col1, Col2, Col3, Col4, Col6, Col7 label Sum(Col5) ''",0),"Select * where Col5>0",0))

Related

Oracle Select unique on multiple column

How can I achieve this to Select to one row only dynamically since
the objective is to get the uniqueness even on multiple columns
select distinct
coalesce(least(ColA, ColB),cola,colb) A1, greatest(ColA, ColB) B1
from T
The best solution is to use UNION
select colA from your_table
union
select colB from your_table;
Update:
If you want to find the duplicate then use the EXISTS as follows:
SELECT COLA, COLB FROM YOUR_TABLE T1
WHERE EXISTS (SELECT 1 FROM YOUR_tABLE T2
WHERE T2.COLA = T1.COLB OR T2.COLB = T1.COLA)
If I correctly understand words: objective is to get the uniqueness even on multiple columns, number of columns may vary, table can contain 2, 3 or more columns.
In this case you have several options, for example you can unpivot values, sort, pivot and take unique values. The exact code depends on Oracle version.
Second option is listagg(), but it has limited length and you should use separators not appearing in values.
Another option is to compare data as collections. Here I used dbms_debug_vc2coll which is simple table of varchars. Multiset except does main job:
with t as (select rownum rn, col1, col2, col3,
sys.dbms_debug_vc2coll(col1, col2, col3) as coll
from test )
select col1, col2, col3 from t a
where not exists (
select 1 from t b where b.rn < a.rn and a.coll multiset except b.coll is empty )
dbfiddle with 3-column table, nulls and different test cases

how to filter result set based on one column distict values and discard rest using oracle

I have a query that returns unique set of records consisting several columns . Even though entire row is unique , columns can can have duplicates . I want to keep only rows that consist of distinct values of certain columns and discard the rest of rows . What is the best method to do it
Sample dataset:
col1 col2 col3 col4
10 Red Book1 Large
10 Blue Book1 Small
20 Blue Book1 Small
30 Red Book2 Medium
30 Blue Book2 Small
desired result
col1 col2 col3 col4
10 Red Book1 Large
30 Red Book2 Medium
above example I keep the col3 distinct and discard rest randomly.
This will work for your example:
with test (col1, col2, col3, col4) as
(
select 10, 'Red', 'Book1', 'Large' from dual union all
select 10, 'Blue','Book1', 'Small' from dual union all
select 20, 'Blue','Book1', 'Small' from dual union all
select 30, 'Red', 'Book2', 'Medium' from dual union all
select 30, 'Blue','Book2', 'Small' from dual
)
select col1, col2, col3, col4
from (
select col1, col2, col3, col4,
row_number() over ( partition by col3 order by col2 desc) countCol3
from test
)
where countCol3 = 1
Here I decided to keep, in case of more than one row wit the same value of col3, the row with the minimum value of col2; this is only to fit your example, so you should edit the ordering part to better fit your need.

Hive collect_list() does not collect NULL values

I am trying to collect a column with NULLs along with some values in that column...But collect_list ignores the NULLs and collects only the ones with values in it. Is there a way to retrieve the NULLs along with other values ?
SELECT col1, col2, collect_list(col3) as col3
FROM (SELECT * FROM table_1 ORDER BY col1, col2, col3)
GROUP BY col1, col2;
Actual col3 values
0.9
NULL
NULL
0.7
0.6
Resulting col3 values
[0.9, 0.7, 0.6]
I was hoping that there is a hive solution that looks like this [0.9, NULL, NULL, 0.7, 0.6] after applying the collect_list.
This function works like this, but I've found the following workaround.
Add a case when statement to your query to check and keep NULLs.
SELECT col1,
col2,
collect_list(CASE WHEN col3 IS NULL THEN 'NULL' ELSE col3 END) as col3
FROM (SELECT * FROM table_1 ORDER BY col1, col2, col3)
GROUP BY col1, col2
Now, because you had a string element ('NULL') the whole result set is an array of strings.
At the end just convert the array of strings to an array of double values.
Note: If your column is STRING it won't be having a NULL value even though your external file does not have any data for that column
you can a where condition with validation check like "col3 is NULL and
col3 is not NULL"

SQL*Plus spooling to .xls/.html help, need tables to be side by side

So I have my settings as:
set entmap off
set feedback off
set verify off
set und off
set pagesize 100
set linesize 200
set markup html on
preformat off
entmap on
spool on
spool \\...\...\test.xls
......... 4 select queries ..........
set markup html off
spool off
The output shows the 4 tables stacked vertically in the .xls spreadsheet aligned to the left starting at A1, but is there a way for me to have solely the first 3 vertically stacked, with the 4th table to the right of the 3rd/lowest table which would start at cell T23?
Do something like this
-- Query 1
SELECT *
FROM TABLE1
WHERE WHATEVER = SOMETHING_ELSE;
-- Query 2
SELECT *
FROM TABLE2
WHERE YADA_YADA = THIS_N_THAT;
-- Queries 3 and 4
SELECT NVL(q3.RNUM, q4.RNUM) AS RNUM, q3.COL1, Q3.COL2, Q3.COL3,
' ' AS SPACER,
Q4.COL4, Q4.COL5, Q4.COL6
FROM (SELECT ROWNUM AS RNUM, COL1, COL2, COL3,
NULL AS COL4, NULL AS COL5, NULL AS COL6
FROM TABLE3) q3
FULL OUTER JOIN (SELECT ROWNUM AS RNUM, NULL AS COL1, NULL AS COL2, NULL AS COL3,
COL4, COL5, COL6
FROM TABLE4) q4
ON q4.RNUM = q3.RNUM;
In this way you get the data from query #4 to the right of the rows from query #3.
SQLFiddle here
IF you want formatting of output you need to use either the UTL_FILE package or the DBMS_OUTPUT package - to write to files or the tty respectively. UTL_FILE may require your DBA to make an addition to the ALL_DIRECTORIES view so your directory object is defined. In other words you cannot just write to any folder you want.
These packages use syntax for output somewhat akin to C printf statements.
See:
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_output.htm#BABJCAJA
Consider this a 'partial' answer.
I'm the Product Manager for Oracle SQL Developer, and we have a new utility, SQLcl.
You can set your SQLFORMAT to CSV or to HTML.
Any resultset is automatically formatted to that, no extra coding required.
It's still in beta, hence the partial status.
Slidedeck and video here.

sort only particular rows sql server

I have six rows like
col1 col2
--------------
Apple 120
XApple 140
Banana 130
Xbanana 150
Car 110
XCar 160
I would like to sort these rows on col2 but leave the rows with 'X' alone.
so after sorting the rows should be like
col1 col2
--------------
Car 110
Apple 120
Banana 130
XCar 160
XApple 140
Xbanana 150
meaning, the rows with car apple and banana should be sorted but the rows with xcar, xapple and xbanana should be left alone and just be appended at the end.
I tried
select *
from table
where col1 not like 'X%' order by col2
union
select *
from table
where symbol like 'X%'
but sql server doesn't allow that. Could anybody point me to the right direction or tell me that this is not possible?
PS: any LINQ solution will also be fine.
thanks
Order by whether the first character of col1 is 'X' or not, and then by col2.
Example:
SELECT *
FROM table
ORDER BY CASE WHEN col1 LIKE 'X%' THEN 1 ELSE 0 END,col2
Although, this doesn't leave the LIKE 'X%' rows unordered, neither did your example.
There is no order without an explicit ORDER BY clause. While you can use UNION to group the rows, you cannot guarantee that the order of the unordered rows is stable. See here.
The following will split the list into two groups of rows, but each will be sorted by Col1:
select Col1, Col2
from (
select Col1, Col2, 1 as PleaseSort
from MyTable
where Col1 not like 'X%'
union
select Col1, Col2, 0
from MyTable
where Col1 like 'X%' ) as PlaceHolder
order by PleaseSort desc, Col1
If you know the sort of upper limit for how many x rows you'll get then you could do something like....
select * from (select top 5000 col1 from #tmp order by col1) a
union
select col1 from #tmp

Resources