# Dual Output (Detail + Windowed Aggregation) (FlinkSQL)

## Prompt
I need you to write a Flink SQL that uses the built-in datagen connector to simulate an order stream, simultaneously outputting detail records to `console1` and windowed aggregation results over a 1-minute tumbling window to `console2`.

**Business Background and Objective**: Generate an order event stream using a datagen built-in table at a rate of 2000 rows per second. Fields include `order_id` (order ID), `user_id` (user ID, 1–10,000), and `amount` (order amount, 0–1000). Use `LOCALTIMESTAMP` as the event time and set a 5-second watermark delay.

The same source data must be simultaneously output to two sinks:
- `console1`: Detail passthrough, directly outputting the original fields
- `console2`: Aggregation over a 1-minute `TUMBLE` tumbling window, grouped by `user_id` to compute the order count and total amount

**Source Table Definition**:
- `order_source` (datagen connector):
  - `order_id BIGINT`: Order ID, randomly generated
  - `user_id INT`: User ID, randomly generated in the range 1–10,000
  - `amount DOUBLE`: Order amount, randomly generated in the range 0–1000
  - `event_time`: Uses `LOCALTIMESTAMP` to generate event time, with a WATERMARK delay of 5 seconds
  - Generation rate: `rows-per-second = 2000`

**Output Table 1 Definition**:
- `console1` (print connector, detail output):
  - `order_id BIGINT`
  - `user_id INT`
  - `amount DOUBLE`

**Output Table 2 Definition**:
- `console2` (print connector, aggregation output):
  - `window_start TIMESTAMP(3)`: Window start time
  - `user_id INT`: User ID
  - `order_cnt BIGINT`: Order count within the window
  - `total_amount DOUBLE`: Total order amount within the window

**Aggregation Logic**:
- Detail output: Direct passthrough from `order_source`
- Aggregation output: `TUMBLE` 1-minute tumbling window, `GROUP BY user_id`
- Aggregation metrics: `COUNT(*) AS order_cnt`, `SUM(amount) AS total_amount`

**Output Requirements**:
- Use two `INSERT INTO` statements to write to `console1` and `console2` respectively.
- `console1` output field order: `order_id`, `user_id`, `amount`
- `console2` output field order: `window_start`, `user_id`, `order_cnt`, `total_amount`

## Reference Solution
-- flinksql_018: 双输出 (明细 + 窗口聚合)
-- 生成 2000 行/秒的订单事件流

-- 1. 订单事件流 datagen 源表
CREATE TABLE order_source (
    order_id BIGINT,
    user_id INT,
    amount DOUBLE,
    event_time AS LOCALTIMESTAMP,
    WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
    'connector' = 'datagen',
    'rows-per-second' = '2000',
    'fields.order_id.kind' = 'random',
    'fields.order_id.min' = '1',
    'fields.order_id.max' = '1000000000',
    'fields.user_id.kind' = 'random',
    'fields.user_id.min' = '1',
    'fields.user_id.max' = '10000',
    'fields.amount.kind' = 'random',
    'fields.amount.min' = '0',
    'fields.amount.max' = '1000'
);

-- 2. Console1: 明细透传输出表
CREATE TABLE console1 (
    order_id BIGINT,
    user_id INT,
    amount DOUBLE
) WITH (
    'connector' = 'print'
);

-- 3. Console2: 窗口聚合输出表
CREATE TABLE console2 (
    window_start TIMESTAMP(3),
    user_id INT,
    order_cnt BIGINT,
    total_amount DOUBLE
) WITH (
    'connector' = 'print'
);

-- 4. 明细透传：直接输出原始字段
INSERT INTO console1
SELECT
    order_id,
    user_id,
    amount
FROM order_source;

-- 5. 窗口聚合：TUMBLE 1min 按 user_id 分组统计
INSERT INTO console2
SELECT
    TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start,
    user_id,
    COUNT(*) AS order_cnt,
    SUM(amount) AS total_amount
FROM order_source
GROUP BY TUMBLE(event_time, INTERVAL '1' MINUTE), user_id;