kdb/q update a keyed table element's list element - insert-update

I have a table like:
q)tbl[`XXX]
1977 1987 1997
and I want to update the nth element from the list of years, so the above becomes
q)tbl[`XXX]
1997 1987 2007
And need it to be inplace?
Been looking into the docs but having hard figuring it out.

You can think of the table as a flipped dictionary.
To do a dictionary update, you index in on key first:
q)tbl:([]XXX:1977 1987 1997)
q)dict:flip tbl
q)dict[`XXX;n]:2007
q)dict
XXX| 1977 1987 2007
Therefore to do an inplace update on a table the following syntax is used:
q)tbl:([]XXX:1977 1987 1997)
q)tbl[`XXX]
1977 1987 1997
q)tbl[n;`XXX]:2007
q)tbl[`XXX]
1977 1987 2007

qsql version of Jamies answer:
q)update XXX:2007 from `tbl where i=n
This will also allows you to use where clause based on other columns in the table

Related

Couchbase multi-dimensional keys

I'm newbie to Couchbase and trying to understand whether it fits my domain.
I have following data:
Birth City Name
1980 A John
1981 B Rick
1982 A Ase
1983 C Max
1984 C Bob
1980 A Rick
1983 D John
1982 A Bob
1985 C Bob
And not getting on how to implement similar to following SQL query:
SELECT birth FROM tbl WHERE city in (A,C) and name (Bob, Rick)
to get following data:
1984 C Bob
1980 A Rick
1982 A Bob
1985 C Bob
One big difference to 'startkey' and 'endkey' view usages is that it's not range selection, it's two different dimension values.
In my real scenario I need to put 1-5000 ID's into 'IN' statement.
The only one way I found is to use indexing and N1ql http://docs.couchbase.com/prebuilt/n1ql/n1ql-dp3/#create-index.html but it seems not the fastest way to access data.
What's the best practice to access multi-dimensional key data with lots of keys values?
Is it okay to create big 'in' statements in N1ql?
You should do a view with the emit function, including a key with two dimension values, and returning the value, in this way:
emit([doc.Name, doc.City], doc.Birth);
And you will have to query it with the param keys:
keys=[["Bob", "A"], ["Bob", "C"], ["Rick", "A"], ["Rick", "C"]]

SSRS Combining values within columns from multiple rows when grouped

I feel like this should be relatively easy to do in a SSRS report. Using VS 2010. I have a table that comes in from a basic sql query. Just dropping the columns into the a table in visual studio. I want to group the table by company first, which I do via the row group properties. I have a table that looks like this.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James A 2010
Bank2 Dave Steve B 2010
Bank2 Dave Mark B 2010
Bank2 Dave James A 2011
Bank2 Dave Steve A 2011
Bank2 Dave Mark B 2011
Bank2 Dave James A 2012
Bank2 Dave Steve A 2012
Bank2 Dave Mark A 2012
I now want to combine the Contact Subs and their subcert joined into one row. BUT only using the most recent year. Because some ContactSub may have had their SubCert upgraded to an A from a B.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark A,A,A 2012
I added an additional gorup by property, the "Year" column to the row and used this formula for the ContactSub and SubCert columns in the table:
=Join(LookupSet(Fields!Company.Value,Fields!Company.Value,Fields!SubCert.Value,"DataSet Name"),",")
But this returned me:
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark,James A,B,B,A, 2012
Steve,Mark,James, Steve A,B,A,A,
Mark A
How could I clarify my formula to make it say for only the newest year instead of using the values for all years?
Hope this makes sense.
With your data:
And a table grouped on Company:
I use the following expressions:
ContactSub
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!ContactSub.Value
, "DataSet1"), ",")
SubCert
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!SubCert.Value
, "DataSet1"), ",")
You can see I'm using Max(Fields!Year.Value) as well as Fields!Company.Value to only match on the highest year in the LookupSet expression.
This gives the required results:
Your problem is that it's working as intended - the LOOKUPSET() function is returning all records from your dataset where the Company matches. You need to either tighten your criteria in your use of the LOOKUPSET() function, or add some custom code to go through the returned array and purge duplicates.
One option for tightening up the lookup might be to add a calculated field to your dataset that concatenates the Company name and the Year together, which, at least looking at your sample data, would provide the slightly more unique key you're looking for.

How to create an SQL query that takes values on different rows and joins them together on the same row (variable number of joins required)

Not sure how to phrase the question really, but here's what I have and here's what I need.
I've got a table that looks like this:
Name K% Year
Albert Pujols 7.90% 2006
Albert Pujols 8.50% 2007
Albert Pujols 8.40% 2008
Albert Pujols 9.10% 2009
Albert Pujols 10.90% 2010
Albert Pujols 8.90% 2011
Albert Pujols 11.30% 2012
I'd like to create a query that will produce output that looks like:
Albert Pujols 7.90% 8.50% 8.40% 9.10% 10.90% 8.90% 11.30%
While this particular player has 7 rows, I can't be guaranteed that such will exist.
Is this even possible?
I'd appreciate any help. I wouldn't have any trouble if I knew that there were only 2 rows (inner join on name)... but the variable number of rows is throwing me for a loop.
Edit**
Peter Wooster's answer of pivoting was the solution I needed.
If you are doing this so you can print a report, best thing to do is use a report writer that supports cross tabs. Jasper Reports does.
SQL is not really good at this kind of stuff. There are tricky ways you could get it to give you the results, but they'd be pretty silly.

SQL query. An unusual join. DB implemented in sqlite-3

This is essentially a question about constructing an SQL query. The db is implemented with sqlite3. I am a relatively new user of SQL.
I have two tables and want to join them in an unusual way. The following is an example to explain the problem.
Table 1 (t1):
id year name
-------------------------
297 2010 Charles
298 2011 David
300 2010 Peter
301 2011 Richard
Table 2 (t2)
id year food
---------------------------
296 2009 Bananas
296 2011 Bananas
297 2009 Melon
297 2010 Coffee
297 2012 Cheese
298 2007 Sugar
298 2008 Cereal
298 2012 Chocolate
299 2000 Peas
300 2007 Barley
300 2011 Beans
300 2012 Chickpeas
301 2010 Watermelon
I want to join the tables on id and year. The catch is that (1) id must match exactly, but if there is no exact match in Table 2 for the year in Table 1, then I want to choose the year that is the next (lower) available. A selection of the kind that I want to produce would give the following result
id year matchyr name food
-------------------------------------------------
297 2010 2010 Charles Coffee
298 2011 2008 David Cereal
300 2010 2007 Peter Barley
301 2011 2010 Richard Watermelon
To summarise, id=297 had an exact match for year=2010 given in Table 1, so the corresponding line for id=297, year=2010 is chosen from Table 2. id=298, year=2011 did not have a matching year in Table 2, so the next available year (less than 2011) is chosen. As you can see, I would also like to know what that matched year (whether exactly , or inexactly) actually was.
I would very much appreciate (1) an indication (yes/no answer) of whether this is possible to do in SQL alone, or whether I need to look outside SQL, and (2) a solution, if that is not too onerous.
Sure, you can do this in SQL. What you need for the first step is a query which joins t1 and t2 on id, and gives you the various possible years (EDIT: fixed this sentence, the original one was incorporating the next step into it as well). You can create a view called t3 which gives you this as follows:
CREATE VIEW [t3] AS
SELECT t1.id as id, t2.year as year FROM t1 INNER JOIN t2 ON (t1.id = t2.id AND T2.year <= t1.year)
From here, you'll want to get the maximum year from t3 per id:
CREATE VIEW [t4] AS
SELECT id, MAX(year) FROM t3 GROUP BY id
You should be able to join t4 back onto t1 and t2 to get what you want. Of course, there are ways to shorten this, but it should get you thinking along the right lines. Also, I'm guessing it's just an example, but please don't call your tables t1, t2, etc.

Rearrange rows and columns in SQL

I need to rearrange rows and columns as per the requirements.
I have data in tables as:
SBU_ID FAC_ID Month Year Venting Combustion Comments
3001 4001 1 2009 5.31 207.11 ABCD
3002 4002 2 2009 15.24 45.12 XYZ
3003 4003 1 2010 8.56 5.00 PQRS
Required format:
Jan-2009 Feb-2009 Jan-2010
SBU_ID FAC_ID Metric Result Comment Result Comment Result Comment
3001 4001 Venting 5.31 ABCD 15.24 XYZ 8.56 PQRS
3001 4001 Combustion 207.11 ABCD 45.12 XYZ 55.00 PQRS
Please advice if this is possible. Thanks.
Google for PIVOT/UNPIVOT functions (if you're talking about MS SQL) or it's analogs for Oracle and other databases.
We don't know if you want to just show the data, or completely transform the table design?
Normally (in first case), you should perform a query (or series of queries) to retrieve particular results from your source data.
Getting the data in required format is not simple using simple query (you don't mention any particular DB Engine). To be honest, I don't even know if it's technically possible to create queries to present columns entries (Venting, Combustion) as rows (series of "group by"s maybe?) without writing a simple application to convert the data.
At SQL Query level don't try to solve this.
Once the query returns all the rows, do this gimmick in your high level code, java or c or what ever.