Need to convert the SQL Query to Gorm query - mysql

I have this SQL query
Select CONCAT(kafka_user_stream.FirstName,' ', kafka_user_stream.LastName) AS "Full Name",
kafka_user_stream.UID AS "User ID",
kafka_user_stream.CountryCode AS "Country",
kafka_user_stream.CreatedAt AS "Registration Date & Time",
COUNT(jackpotmessage_stream.UID) AS "Win Count"
FROM kafka_user_stream LEFT JOIN
jackpotmessage_stream ON jackpotmessage_stream.UID = kafka_user_stream.UID
WHERE "Type"='goldenTicketWin'
GROUP BY "Full Name", "User ID", "Country", "Registration Date & Time"
ORDER BY "Win Count" DESC
I want to convert it to Gorm. I can use it using
err = s.db.Exec("...QUERY")
but i cannot extract data from the above query. I need to extract all of the above fields (Full Name, User ID etc) and store them in a struct.
In above query, kafka_user_stream and jackpot_message are the tables extracted from a kafka stream. I am using go-gorm and go.
I tried the Gorm documentation as well as few other references but I am unable to find any solution. Would be very thankful for any leads, insight or help.

With native go/mysql driver, you should use Query() and Scan() methods to get results from the database and store them in a struct, not Exec().
In GORM, you can use SQL Builder for your custom queries:
type Result struct {
ID int
Name string
Age int
}
var result Result
db.Raw("SELECT id, name, age FROM users WHERE name = ?", 3).Scan(&result)

I figured out a slightly different way as suggested by Aykut which works fine.
rows, _err := s.gdb.Raw(`Select CONCAT(kafka_user_stream.FirstName,' ', kafka_user_stream.LastName) AS "FullName",
kafka_user_stream.UID AS "UserID",
kafka_user_stream.CountryCode AS "Country",
kafka_user_stream.CreatedAt AS "CreatedAt",
COUNT(jackpotmessage_stream.UID) AS "WinCount"
FROM kafka_user_stream LEFT JOIN
jackpotmessage_stream ON jackpotmessage_stream.UID = kafka_user_stream.UID
WHERE "Type"='goldenTicketWin'
GROUP BY "FullName", "UserID", "Country", "CreatedAt"
ORDER BY "WinCount" DESC;`).Rows()

Related

Qlik Sense Pagination with nextToken and currentToken

I am looking for help on how to get all records in Qlik Sense from a data source, which works with pagination (currentToken and nextToken).
So far everything I have tried always gives me only the first 100 records, which is basically the limitation of the tool I am trying to get data from.
This is how my script looks:
LIB CONNECT TO 'REST_CALL';
// Action required: Implement the logic to retrieve the total records from the REST source and assign to the 'total' local variable.
Let total = 0;
Let totalfetched = 0;
Let startAt = 0;
Let pageSize = 100;
for startAt = 0 to total step pageSize
RestConnectorMasterTable:
SQL SELECT
"__KEY_root",
(SELECT
"limit",
"totalCount",
"nextToken",
"currentToken",
"__KEY_paging",
"__FK_paging",
(SELECT
"__KEY__links",
"__FK__links",
(SELECT
"href",
"__FK_next"
FROM "next" FK "__FK_next"),
(SELECT
"href" AS "href_u0",
"__FK_self"
FROM "self" FK "__FK_self")
FROM "_links" PK "__KEY__links" FK "__FK__links")
FROM "paging" PK "__KEY_paging" FK "__FK_paging"),
(SELECT
"id" AS "id_u0",
"title",
"code",
"description",
"start",
"end",
"closeAfter",
"archiveAfter",
"launchAfter",
"timezone",
"defaultLocale",
"currency",
"registrationSecurityLevel",
"status",
"eventStatus",
"testMode",
"created",
"lastModified",
"virtual",
"format",
"type" AS "type_u0",
"capacity",
"__KEY_data",
"__FK_data",
(SELECT
"name",
"__KEY_venues",
"__FK_venues",
(SELECT
"city",
"country",
"countryCode",
"latitude",
"longitude",
"address1",
"region",
"regionCode",
"postalCode",
"__FK_address"
FROM "address" FK "__FK_address")
FROM "venues" PK "__KEY_venues" FK "__FK_venues"),
(SELECT
"firstName",
"lastName",
"email",
"prefix",
"__FK_planners"
FROM "planners" FK "__FK_planners"),
(SELECT
"id",
"name" AS "name_u0",
"type",
"order",
"__KEY_customFields",
"__FK_customFields",
(SELECT
"#Value",
"__FK_value"
FROM "value" FK "__FK_value" ArrayValueAlias "#Value")
FROM "customFields" PK "__KEY_customFields" FK "__FK_customFields"),
(SELECT
"name" AS "name_u1",
"__FK_category"
FROM "category" FK "__FK_category"),
(SELECT
"__KEY__links_u0",
"__FK__links_u0",
(SELECT
"href" AS "href_u1",
"__FK_invitation"
FROM "invitation" FK "__FK_invitation"),
(SELECT
"href" AS "href_u2",
"__FK_agenda"
FROM "agenda" FK "__FK_agenda"),
(SELECT
"href" AS "href_u3",
"__FK_summary"
FROM "summary" FK "__FK_summary"),
(SELECT
"href" AS "href_u4",
"__FK_registration"
FROM "registration" FK "__FK_registration")
FROM "_links" PK "__KEY__links_u0" FK "__FK__links_u0"),
(SELECT
"#Value" AS "#Value_u0",
"__FK_languages"
FROM "languages" FK "__FK_languages" ArrayValueAlias "#Value_u0")
FROM "data" PK "__KEY_data" FK "__FK_data")
FROM JSON (wrap on) "root" PK "__KEY_root"
WITH CONNECTION(
QUERY "startAt" "$(startAt)",
URL "https://api-platform.sample.com/sample/sample",
QUERY "filter" "sample.id eq '123456789'",
HTTPHEADER "Authorization" "Bearer $(vToken)"
);
NEXT startAt;
I tried to define the 'total' variable as follows so I can loop through all the records for the specific sample.id used above(948):
LET total=peek('totalCount');
TRACE $(total);
But the result is that it just loads the first 100 records 10 times.
Currently these are the settings of my connection:
Key Generation Strategy - SequenceID
Pagination Type - Custom
I tried also the next token pagination type, but it was also getting only the first 100 records.
My guess is that I have to somehow implement the nextToken and currentToken in the WITH CONNECTION part of my script, problem is that I don't know how to do that and if it is indeed what needs to be done.
Thanks in advance!

How to query multiplte row in one json object

table provider
table provider_properties
here I wanted the result something like
{
"provider_uuid": "b897f790-ee90-4869-9345-690380b1a0c9",
"name": "Provider 1",
"password": "112233",
"username": "provider_1",
"properties": {
"address_1": "Dubai",
"address_2": "NY"
}
}
here i tried something like
SELECT provider.*, json_object(provider_properties.key_name, provider_properties.key_value) as properties FROM provider JOIN provider_properties on provider.provider_id = provider_properties.provider_uuid;
but the problem is i am getting 2 rows
Since your expected results need specific formatting in json. You want to refer to JSON Formatted output. This is for shell though.
You might also want to try this...
This would give you a tabular results but in one row.
SELECT
provider.*,
p_props.properties
FROM provider
JOIN (
provider_uuid,
SELECT JSON_OBJECTAGG(
provider_properties.key_name,
provider_properties.key_value
) as properties
FROM provider_properties
GROUP BY provider_uuid
) p_props ON provider.provider_id = p_props.provider_uuid;
CONCAT() and REPLACE() here are used for sorting the order of columns.
I would say the use of REPLACE() here is quite risky, please test it out and see how it goes.
db<>fiddle
SELECT
p.*,
CONCAT(
'{"', 'provider_uuid": "', pp.provider_uuid, '"',
REPLACE(JSON_OBJECT('name', p.name, 'password', p.password,
'username', p.username, 'properties', pp.name_value), '{"name', ', "name')
) AS your_json
FROM provider p
JOIN (
SELECT provider_uuid, JSON_OBJECTAGG(key_name, key_value) as name_value
FROM provider_properties
GROUP BY provider_uuid
) pp ON p.provider_id = pp.provider_uuid;

How to write one n1ql query to sum values from multiple documents in the same bucket

I am a newbie to Couchbase DB server and I am trying to achieve with one query what I have done with three queries as this is not so efficient.
I have three different documents types (x,y,z) in the same bucket; all having a similar key: 'district' like so:
document x:
{
"type": "x",
"district": "Some district"
}
document y:
{
"type": "y",
"district": "Some district"
}
document z:
{
"type": "z",
"district": "Some district"
}
I have currently implemented something like the following pseudo-code in PHP:
$totalDistrictInX = "SELECT COUNT(x) FROM bucket WHERE type = 'x' AND district = 'Maboro';
$totalDistrictInY = "SELECT COUNT(x) FROM bucket WHERE type = 'y' AND district = 'Maboro';
$totalDistrictInZ = "SELECT COUNT(x) FROM bucket WHERE type = 'z' AND district = 'Maboro';
$totalCountOfMaboro = $totalDistrictInX + $totalDistrictInY + $totalDistrictInZ;
I cannot use a JOIN query because the Couchbase server currently in use is below 5.50 which only supports joining documents between document key to document field and not between document fields.
Is there a way to achieve this with one just n1ql query? Any help will be much appreciated, please.
Use aggregate query without group by for total count, control what documents to count through predicate.
SELECT COUNT(1) AS cnt
FROM bucket
WHERE type IN ['x', 'y', 'z'] AND district = 'Maboro';
If you need count for each type use GROUP BY
SELECT type, COUNT(1) AS cnt
FROM bucket
WHERE type IN ['x', 'y', 'z'] AND district = 'Maboro'
GROUP BY type;
If you want total count and individual type, its counts as array
SELECT ARRAY_SUM(av[*].cnt) AS totalcnt, av AS details
LET av = (SELECT type, COUNT(1) AS cnt
FROM bucket
WHERE type IN ['x', 'y', 'z'] AND district = 'Maboro'
GROUP BY type);
Could a GROUP BY and COUNT combo be your solution?
SELECT COUNT(x) FROM bucket WHERE district = 'Maboro' GROUP BY type
Documentation

create a set expression for a cell in a table report

I have a report which creates a spreadsheet. one cell could have data from one of three fields depending on a fourth field status or field two being blank..
I was thinking of writing as CASE statement but that does not work in ssrs.
The IIF statement works great for 2 values but how do you write for three values?
In common language it would be "If secondary value ="Yes", use secondary name, If account field value is Null, use Contact field value, otherwise use account field value"
Thanks
You can use nested IIF statements but they quickly get messy. You should use SWITCH which acts a bit like a case statement.
A simple example would be
= SWITCH(
Fields!myFirstField.Value = <10 , "Small",
Fields!myFirstField.Value = <30 , "Medium",
Fields!myFirstField.Value = <80 , "Large",
True , "HUGE",
)
As switch stops at the first true expression there is not need to check ranges of values if you get them in the correct order.
The final "True" expression just acts like an ELSE
If you need to check multiple criteria per condition then you can do that too like this..
= SWITCH(
Fields!myFirstField.Value = <10 AND Fields!mySecondField.Value = 1 , "Small Cat",
Fields!myFirstField.Value = <10 AND Fields!mySecondField.Value = 2 , "Small Dog",
Fields!myFirstField.Value = <30 , "Medium Animal",
Fields!myFirstField.Value = <80 , "Large Animal",
True , "HUGE Animal",
)

How to pass a variable into Subquery with n1ql?

In my situation, entreprise(company) can have several sites(filiales), I want to get all the filiales with format array.
In the json entreprise(company), there is no information of sites(filiales), In the json sites(filiales), it has entreprise(company) uid.
Json entreprise(company):
{
"type": "entreprise",
"dateUpdate": 1481716305279,
"owner": {
"type": "user",
"uid": "PNnqarPqSdaxmEJ4DoMv-A"
}
}
Json sites(filiales):
{
"type": "site",
"entreprise": {
"uid": "3c0CstzsTjqPdycL5yYzJQ",
"type": "entreprise"
},
"nom": "test"
}
The query I tried:
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (SELECT d.* FROM default d WHERE d.type = "site" AND d.entreprise.uid = uid) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise";
Result: error
{
"code": 5010,
"msg": "Error evaluating projection. - cause: FROM in correlated subquery must have USE KEYS clause: FROM default."
}
Then i use alias:
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (SELECT d.* FROM default d WHERE d.type = "site" AND d.entreprise.uid = META(entreprise).id) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise";
Result: sites array is empty.
First you have to create an index on your site documents :
CREATE INDEX site_ent_idx ON default(entreprise.uid) WHERE type="site";
Then change your query to use the new index :
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (
SELECT site.*
FROM default as ent USE KEYS META(entreprise).id
JOIN default as site ON KEY site.entreprise.uid FOR ent
) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise"
This solution should meet your needs.
You need to perform an index join from sites to enterprises. See https://dzone.com/articles/join-faster-with-couchbase-index-joins
After that, use GROUP BY and ARRAY_AGG() to collect the sites into arrays.