ささいなことですが。

Windowsアプリテスト自動化ライブラリFriendly開発者の日記です。

LambdicSql - α51 その他

パラメータ名称

@p_0って感じで連番にしていました。折角変数名を使っているのだから、それを変数名に使った方が良いとの意見をいただそのようにしました。

public void ParamName()
{
    var min = 3000;
    var max = 4000;

    var query = Db<DB>.Sql(db =>
        Select(new
        {
            money = db.tbl_remuneration.money,
        }).
        From(db.tbl_remuneration).
        Where(min < db.tbl_remuneration.money && db.tbl_remuneration.money < max));

    var info = query.Build(cnn.GetType());
    Debug.Print(info.SqlText);
}
SELECT
	tbl_remuneration.money AS "money"
FROM tbl_remuneration
WHERE ((@min) < (tbl_remuneration.money)) AND ((tbl_remuneration.money) < (@max))

ただ、一つの関数内で完結していれば、問題ないのですが、LambdicSqlは式を組み合わせることができるので、変数名も重複する可能性があります。
その場合は、_がついていくことになります。

public void ParamName2()
{
    var min = 3000;
    var max = 4000;

    var query = Db<DB>.Sql(db =>
        Select(new
        {
            money = MoneyExp(5, 10).Cast<decimal>(),
        }).
        From(db.tbl_remuneration).
        Where(min < db.tbl_remuneration.money && db.tbl_remuneration.money < max));

    var info = query.Build(cnn.GetType());
    Debug.Print(info.SqlText);
}
public ISqlExpression<decimal> MoneyExp(int min, int max)
    => Sql<Data>.Create(db => db.tbl_remuneration.money + min + max);
SELECT
	((tbl_remuneration.money) + (@min)) + (@max) AS "money"
FROM tbl_remuneration
WHERE ((@min_) < (tbl_remuneration.money)) AND ((tbl_remuneration.money) < (@max_))

Window関数対応

Window関数に対応しました。こんな感じで使えます。

public void TestWindow()
{
    var query = Db<DB>.Sql(db =>
        Select(new SelectData()
        {
            Avg = Window.Avg(db.tbl_remuneration.money).
                    Over<decimal>(null,
                        new OrderBy(new Asc(db.tbl_remuneration.payment_date)),
                        null),
            PaymentDate = db.tbl_remuneration.payment_date
        }).
        From(db.tbl_remuneration));

    //to string and params.
    var info = query.Build(_connection.GetType());
    Debug.Print(info.SqlText);

    //dapper
    var datas = _connection.Query<SelectData>(info.SqlText, info.Parameters).ToList();
}
SELECT
	AVG(tbl_remuneration.money)OVER(
	ORDER BY
		tbl_remuneration.payment_date ASC) AS "Avg",
	tbl_remuneration.payment_date AS "PaymentDate"
FROM tbl_remuneration

一気に書いても良いのですが、以下のように分けて書くことも可能です。

var avg = Db<DB>.Sql(db => Window.Avg(db.tbl_remuneration.money).
                Over<decimal>(null,
                    new OrderBy(new Asc(db.tbl_remuneration.payment_date)),
                    null));
//make sql.
var query = Db<DB>.Sql(db =>
    Select(new SelectData()
    {
        Avg = avg,
        PaymentDate = db.tbl_remuneration.payment_date
    }).
    From(db.tbl_remuneration));

それでWindow関数の書式なのですが、以下のようなものになっています。Window関数はいくつかは普通の集約関数と同名ですので、using staticはしない方が良いですね。

var avg = Db<DB>.Sql(db =>
        //関数
        Window.Avg(db.tbl_remuneration.money).
        //不要な部分はnullを入れる
        Over<decimal>(
            //Partitionを指定 複数指定可能
            new PartitionBy(db.tbl_staff.name, db.tbl_remuneration.payment_date),
            //OrderByを指定 複数指定可能
            new OrderBy(new Asc(db.tbl_remuneration.money), new Desc(db.tbl_remuneration.payment_date)),
            //Rowsを指定 引数は一つの場合はPRECEDINGのみの指定となる
            new Rows(1, 5)));